diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index b37087c..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.ibm.com.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 184fbc1..0000000
--- a/Makefile
+++ /dev/null
@@ -1,86 +0,0 @@
-# Top Makefile
-
-all:: compile jars docs apidocs package
-
-TOP = .
-include $(TOP)/src/Makefile.incl
-
-compile:: compile_src compile_samples
-package:: package_bin package_src 
-
-compile_src::
-	@echo Building Source
-	${MAKE} -C src
-
-compile_samples:: compile_src
-	@echo Building Samples
-	${MAKE} -C samples
-
-jars:: compile
-	@echo Building Jar files in bin directory
-	${MKDIR} class
-	${MKDIR} bin
-	${MAKE} -C src jars
-
-docs:: ./src/classfiles_updated
-	@echo Building Stylebook docs in docs directory
-	${MKDIR} docs/html
-	$(STYLEBOOK) "targetDirectory=docs/html" docs/docs-book.xml tools/style-apachexml.jar
-
-apidocs::
-	@echo Building apiDocs in docs directory.
-	${MKDIR} docs/apiDocs
-	${MAKE} -C src apidocs
-
-package_bin:: jars apidocs ${BINZIPFILE}
-${BINZIPFILE}:: ./src/classfiles_updated
-
-	@echo Building the binary release package
-	${MKDIR} bin
-	${MKDIR} bin/samples
-	${MKDIR} bin/samples/dom
-	${CP} samples/dom/*.java bin/samples/dom
-	${MKDIR} bin/samples/dom/traversal
-	${CP} samples/dom/traversal/*.java bin/samples/dom/traversal
-	${MKDIR} bin/samples/dom/wrappers
-	${CP} samples/dom/wrappers/*.java bin/samples/dom/wrappers
-	${MKDIR} bin/samples/sax
-	${CP} samples/sax/*.java bin/samples/sax
-	${MKDIR} bin/samples/sax/helpers
-	${CP} samples/sax/helpers/*.java bin/samples/sax/helpers
-	${MKDIR} bin/samples/ui
-	${CP} samples/ui/*.java bin/samples/ui
-	${MKDIR} bin/samples/util
-	${CP} samples/util/*.java bin/samples/util
-	${CP} -r docs bin
-	${RM} -r bin/docs/CVS
-	${RM} -r bin/docs/dtd/CVS
-	${RM} -r bin/docs/*.xml bin/docs/dtd/*.dtd bin/docs/dtd/*.ent
-	${CP} -r data bin
-	${RM} -r bin/data/CVS
-	${CP} LICENSE bin
-	$(MV) bin xerces-${PRODUCTVERSION}
-	$(JAR) cvfM ${BINZIPFILE} xerces-${PRODUCTVERSION} 
-	$(MV) xerces-${PRODUCTVERSION} bin
-
-package_src:: ${SRCZIPFILE}
-${SRCZIPFILE}: ./src/classfiles_updated
-	@echo Building the source release package
-	${MAKE} -C src package_src
-	${CP} -r data source
-	${RM} -r source/data/CVS
-	${MKDIR} source/docs
-	${MKDIR} source/docs/dtd
-	${CP} docs/*.xml source/docs
-	${CP} LICENSE source
-	${CP} docs/dtd/*.dtd source/docs/dtd
-	${CP} docs/dtd/*.ent source/docs/dtd
-	$(MV) source xerces-${PRODUCTVERSION}
-	$(JAR) cvfM ${SRCZIPFILE} xerces-${PRODUCTVERSION} 
-	$(MV) xerces-${PRODUCTVERSION} source
-
-clean::
-	${MAKE} -C src clean
-	${MAKE} -C samples clean
-	${RM} -rf bin class source docs/apiDocs docs/html 
-	${RM} ${BINZIPFILE} ${SRCZIPFILE}
diff --git a/README b/README
deleted file mode 100644
index ec677ce..0000000
--- a/README
+++ /dev/null
@@ -1,89 +0,0 @@
-			Xerces Java Build Instructions
-
-Table of Contents
-
- 1. Building Xerces
- 2. Building Documentation
- 3. Special Instructions
-    3.1 Building on Windows Platform
-    3.2 Building on UNIX Platform
-
----------------------------------------------------------------------
-
-1. Building Xerces
-
-   The top level Makefile will build everything, including the
-   documentation. If you only want to compile the source code and
-   make the JAR files, run the following command from the top of
-   the Xerces Java tree:
-   
-     make jars
-     
-   If you want to build everything, including the documentation,
-   read the following instructions before running make.
-   
-   When building, all special instructions must be followed.
-
-2. Building Documentation
-
-   You must download the tools required for building the documentation
-   from the distribution page (http://xml.apache.org/dist/). Download 
-   the following tools ZIP file:
-
-     Xerces-J-tools.x.y.z.zip
-
-   where "x.y.z" is either the exact version or the version just before
-   the version of the Xerces-J parser for which you want to build the
-   documentation. Extract the tools package in the top directory of the
-   Xerces Java tree so that you get something like:
-
-     xerces_a_b_c/tools
-
-   Then, from the top of the Xerces Java tree, type the following
-   command to build the documentation:
-   
-     make docs apidocs
-
-3. Special Instructions
-
-3.1 Building on Windows Platform
-
-    First, you need a copy of Cygnus's Cygwin. See
-    http://sourceware.cygnus.com/cygwin.
-
-    If your JDK is properly installed on your system, you do not need 
-    to set any CLASSPATH to build Xerces. If you have one, make sure 
-    it does not end with a '\' or it will cause the build to fail.
-
-    If you're using JDK 1.1 and want to build the documentation you 
-    then need to specify where the JDK 1.2 java and javadoc programs
-    are by setting the variable JDK12BIN in your environment with 
-    something like:
-
-      set JDK12BIN=C:/jdk1.2.2/bin
-
-    Note the use of forward slashes! Depending on which version of 
-    make you are using having blackshlashes there may cause the build 
-    to fail.
-
-    Then, if you're not using the Cygwin bash shell, you need to set
-    the variable MAKE_MODE in your environment like this:
-
-      set MAKE_MODE=UNIX
-
-    Finally, from the top of the Xerces Java tree, run make.
-
-3.2 Building on Unix Platform
-
-    If your JDK is properly installed on your system, you do not 
-    need to set any CLASSPATH to build Xerces.
-
-    If you're using JDK 1.1 and want to build the documentation you 
-    then need to specify where the JDK 1.2 java and javadoc programs 
-    are by setting the variable JDK12BIN in your environment with
-    something like:
-
-      set JDK12BIN "/usr/local/jdk-1.2.2/bin"
-
-    Then, from the top of the Xerces Java tree, run make.
-
diff --git a/Readme.html b/Readme.html
deleted file mode 100755
index bc5acc7..0000000
--- a/Readme.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"
-     "http://www.w3.org/TR/REC-html40/strict.dtd">
-<html>
-<head>
-<meta http-equiv="Refresh" content="0; URL=docs/html/index.html">
-<title></title>
-</head>
-<body>
-This document will redirect you to the real documenation which starts at docs/index.html.
-<p>
-If your browser doesn't support redirects, or you are looking at this file from the download 
-package, you will need to go to docs/html/index.html manually.
-</body>
-</html>
diff --git a/STATUS b/STATUS
deleted file mode 100644
index 3fec93c..0000000
--- a/STATUS
+++ /dev/null
@@ -1,54 +0,0 @@
-This is the Status file for the Xerces for Java code base. 
-
-There are lots of things that need to be done: 
-
-* Additional Support for W3C XML schema.  (andyc, ericy, jeffr are
-	working on it)
-
-* Figuring out what support for DTD access should look like.  This
-  version of Xerces supports access to the DTD via a special node in
-  the DOM tree.  There's also room for a more programmatic API to the
-  DTD / Schema.  This is a meaty one, and would be a good place for
-  somebody to jump in and help.
-
-* Enabling support for a DTD Caching mechanism.  This would be
-  especially beneficial in a server environment.  Part of the work
-  that helps Schema will help this. 
-
-* Revalidation architecture work (i.e. How to validate, after a DOM
-  tree has been edited - we used to be able to do this...)
-
-* DOM Write validation (i.e. what is legal to insert here?)
-
-* refinement and extension of the incremental parsing API
-
-* scripts to build parser subconfigurations (i.e. if I don't need
-  WML/WAP, take it out of the jar)
-
-* additional configuration options.
-
-* performance, performance, performance.  Always need help here.
-
-* conformance, conformance, conformance.  We're pretty darn good, but
-  we can always do better.
-
-* a bunch of things that haven't been thought of yet.
-
-* more documentation.  The docs need to be updated, especially the FAQ.
-
-* more samples (lots, especially code fragments that accomplish specific
-  tasks)
-
-* kill bugs (always)
-
-* Major work on the build system.
-  
-  ANT vs Makefiles is the current discussion
-  Is ANT ready for us to use?  It has to get beyond the "compile everything"
-  stage, because we have files (e.g. for Schema) that should NOT be compiled
-  into the build yet.
-
-* Hook up JavaScript DOM API tests (see http://www.nist.gov/xml)
-
-* JAXP Wrappers for Xerces
-  [pending resolution of licensing issues]
diff --git a/build.bat b/build.bat
deleted file mode 100755
index 66efb78..0000000
--- a/build.bat
+++ /dev/null
@@ -1,22 +0,0 @@
-@echo off
-echo Xerces-Java Build System
-echo ------------------------
-
-if "%JAVA_HOME%" == "" goto error
-
-set LOCALCLASSPATH=%JAVA_HOME%\lib\tools.jar;.\tools\ant.jar;.\tools\xerces.jar;.\tools\xalan.jar;.\tools\stylebook-1.0-b2.jar;.\tools\style-apachexml.jar;
-set ANT_HOME=./tools
-
-echo Building with classpath %LOCALCLASSPATH%
-echo Starting Ant...
-%JAVA_HOME%\bin\java.exe -Dant.home="%ANT_HOME%" -classpath "%LOCALCLASSPATH%" org.apache.tools.ant.Main %1 %2 %3 %4 %5
-goto end
-
-:error
-echo "ERROR: JAVA_HOME not found in your environment."
-echo "Please, set the JAVA_HOME variable in your environment to match the"
-echo "location of the Java Virtual Machine you want to use."
-
-:end
-set LOCALCLASSPATH=
-@echo on
diff --git a/build.sh b/build.sh
deleted file mode 100755
index 4932e5b..0000000
--- a/build.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-echo
-echo "Xerces-Java Build System"
-echo "------------------------"
-
-if [ "$JAVA_HOME" = "" ] ; then
-   echo "ERROR: JAVA_HOME not found in your environment."
-   echo 
-   echo "Please, set the JAVA_HOME variable in your environment to match the"
-   echo "location of the Java Virtual Machine you want to use."
-   exit 1
-fi
-
-# UNIX
-CLPATHSEP=:
-# if we're on a Windows box make it ;
-uname | grep WIN && CLPATHSEP=\;
-
-LOCALCLASSPATH="$JAVA_HOME/lib/tools.jar${CLPATHSEP}${JAVA_HOME}/lib/classes.zip${CLPATHSEP}./tools/ant.jar${CLPATHSEP}./tools/xerces.jar${CLPATHSEP}./tools/xalan.jar${CLPATHSEP}./tools/stylebook-1.0-b2.jar${CLPATHSEP}./tools/style-apachexml.jar"
-ANT_HOME=./tools
-
-echo Building with classpath \"$LOCALCLASSPATH\"
-echo Starting Ant...
-echo
-"$JAVA_HOME"/bin/java -Dant.home="$ANT_HOME" -classpath "$LOCALCLASSPATH" org.apache.tools.ant.Main $@
diff --git a/build.xml b/build.xml
deleted file mode 100644
index 7d3291c..0000000
--- a/build.xml
+++ /dev/null
@@ -1,399 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ===================================================================
-
-Build file for Xerces-Java
-
-Notes:
-   This is a build file for use with the Jakarta Ant build tool.
-
-Installation Instructions:
-   To install Ant on your system, you need to checkout the
-   "jakarta-tools" CVS module. Then you should place the files
-     - ant.jar
-     - projectx-tr2.jar
-     - javac.jar
-   in your classpath.
-
-Build Instructions:
-   To build, run
-
-     java org.apache.tools.ant.Main <target>
-
-   on the directory where this file is located with the target you want.
-   There is also a batch file called "build.bat" to invoke Ant from a
-   Windows command line shell. On the UNIX platform, use "build.sh" shell
-   script to invoke Ant.
-
-Most useful targets:
-
- - package -> creates the "xerces.jar" package in "./build"
- - docs -> creates the HTML documentation in "./build/docs"
- - javadocs - crates the javadocs in "./build/javadocs"
- - dist -> creates the complete distribution
- - site -> regenerates the web site
-
-Note:
-
-  In order to regenerate the web site, you must have the "xml-site" and "xml-xerces"
-  CVS modules checked-out in the same directory, or this won't work. for example
-
-    xml.apache.org/xml-site
-    xml.apache.org/xml-xerces
-    ...
-
-  Have fun!
-
-Authors:
-  Stefano Mazzocchi <stefano@apache.org>
-  Anupam Bagchi     <abagchi@apache.org>
-
-Copyright:
-  Copyright (c) 2000 The Apache Software Foundation.
-
-   $Id$
-
-==================================================================== -->
-
-<project default="usage" basedir=".">
-
-  <target name="init">
-    <property name="name" value="xerces"/>
-    <property name="Name" value="Xerces-J"/>
-    <property name="version" value="1.2.0"/>
-    <property name="version_postfix" value="_1_2_0"/>
-    <property name="year" value="1999-2000"/>
-	<property name="copyright" value="Copyright &#169; ${year} Apache XML Project. All Rights Reserved."/>
-
-	<echo message= "---------------- ${Name} ${version} [${year}] ---------------"/>
-    <property name="build.compiler" value="classic"/>
-    <property name="debug" value="off"/>
-    <property name="optimize" value="on"/>
-    <property name="deprecation" value="off"/>
-
-    <property name="src.dir" value="./src"/>
-    <property name="docs.dir" value="./docs"/>
-    <property name="data.dir" value="./data"/>
-    <property name="samples.dir" value="./samples"/>
-    <property name="tests.dir" value="./tests"/>
-    <property name="tools.dir" value="./tools"/>
-    <property name="docs.book" value="${docs.dir}/docs-book.xml"/>
-    <property name="version.file" value="org/apache/xerces/framework/Version.java"/>
-
-    <property name="packages" value="org.*"/>
-
-    <property name="doc.generator" value="org.apache.stylebook.StyleBook"/>
-    <property name="doc.generator.package" value="${tools.dir}/stylebook-1.0-b2.jar"/>
-    <property name="doc.style" value="${tools.dir}/style-apachexml.jar"/>
-
-    <property name="build.dir" value="./build"/>
-    <property name="build.src" value="${build.dir}/src"/>
-    <property name="build.dest" value="${build.dir}/classes"/>
-    <property name="build.docs" value="${build.dir}/docs/html"/>
-    <property name="build.samples" value="${build.dir}/samples"/>
-    <property name="build.tests" value="${build.dir}/tests"/>
-    <property name="build.data" value="${build.dir}/data"/>
-    <property name="build.javadocs" value="${build.dir}/docs/apiDocs"/>
-
-    <property name="distsrc.dir" value="${build.dir}/${Name}-src${version_postfix}"/>
-    <property name="distbin.dir" value="${build.dir}/${Name}-bin${version_postfix}"/>
-
-    <filter token="year" value="${year}"/>
-    <filter token="version" value="${version}"/>
-    <filter token="date" value="${TODAY}"/>
-    <filter token="log" value="true"/>
-    <filter token="verbose" value="true"/>
-
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Help on usage                                                       -->
-  <!-- =================================================================== -->
-  <target name="usage">
-    <echo message=""/>
-    <echo message=""/>
-    <echo message="${Name} Build instructions"/>
-    <echo message="-------------------------------------------------------------"/>
-    <echo message=""/>
-    <echo message=" available targets are:"/>
-    <echo message=""/>
-    <echo message="   compile  --> compiles the source code"/>
-    <echo message="   jar      --> generates the xerces.jar file"/>
-    <echo message="   samples  --> compiles the samples source code"/>
-    <echo message="   tests    --> compiles the tests source code"/>
-    <echo message="   sampjar  --> generates the xercesSamples.jar file"/>
-    <echo message="   jars     --> generates the xerces and xercesSamples jar files"/>
-    <echo message="   docs     --> generates the HTML documentation"/>
-    <echo message="   javadocs --> generates the API documentation (needs Java 1.2 or higher)"/>
-    <echo message="   pack-src --> generates the source distributions of Xerces-Java (zip and tar.gz)"/>
-    <echo message="   pack-bin --> generates the binary distributions of Xerces-Java (zip and tar.gz)"/>
-    <echo message="   all      --> generates the binary and source distributions of Xerces-Java"/>
-    <echo message="   test     --> runs a sanity test on the sample files"/>
-    <echo message="   clean    --> cleans up all generated files and directories"/>
-    <echo message="   usage    --> provides help on using the build tool (default)"/>
-    <echo message=""/>
-    <echo message=" See comments inside the build.xml file for more details."/>
-    <echo message="-------------------------------------------------------------"/>
-    <echo message=""/>
-    <echo message=""/>
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Prepares the build directory                                        -->
-  <!-- =================================================================== -->
-  <target name="prepare" depends="init">
-    <mkdir dir="${build.dir}"/>
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Compiles the source code                                            -->
-  <!-- =================================================================== -->
-  <target name="prepare-src" depends="prepare">
-    <!-- create directories -->
-    <mkdir dir="${build.src}"/>
-    <mkdir dir="${build.dest}"/>
-
-    <!-- copy src files -->
-    <copydir src="${src.dir}" dest="${build.src}" includes="**/Makefile, **/Makefile.incl, javax/**, org/**"
-             excludes="**/classfiles_updated **/CVS* **/.#*
-                       **/SchemaImporter.java **/RevalidatingDOMParser.java
-                       **/DatatypeContentModel.java **/ComplexTypeInfo.java
-                       **/DTDImporter.java "/>
-	<deltree dir="${build.src}/whiteboard"/>
-
-    <!-- substitute tokens as needed -->
-    <replace file="${build.src}/${version.file}" token="@@version@@" value="${version}"/>
-    <!-- <replace file="${build.src}/${version.file}" token="@@year@@" value="${year}"/> -->
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Compiles the source directory                                       -->
-  <!-- =================================================================== -->
-  <target name="compile" depends="prepare-src">
-    <javac srcdir="${build.src}"
-           excludes="**/RevalidatingDOMParser.java "
-    	   destdir="${build.dest}"
-    	   debug="${debug}"
-	       deprecation="${deprecation}"
-	       optimize="${optimize}" />
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Creates the class package                                           -->
-  <!-- =================================================================== -->
-  <target name="jar" depends="compile">
-    <jar jarfile="${build.dir}/${name}.jar"
-         basedir="${build.dest}"
-         includes="org/**, javax/**"/>
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Compiles the samples                                                -->
-  <!-- =================================================================== -->
-  <target name="samples" depends="jar">
-    <mkdir dir="${build.samples}"/>
-    <copydir src="${samples.dir}" dest="${build.samples}" />
-    <javac srcdir="${build.samples}"
-           destdir="${build.dest}"
-           classpath="${build.dir}/${name}.jar"
-           debug="${debug}"/>
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Compiles the tests                                                  -->
-  <!-- =================================================================== -->
-  <target name="tests" depends="samples">
-    <mkdir dir="${build.tests}"/>
-    <copydir src="${tests.dir}" dest="${build.tests}" />
-    <javac srcdir="${build.tests}"
-           destdir="${build.dest}"
-           classpath="${build.dir}/${name}.jar"
-           debug="${debug}"/>
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Creates the samples package                                         -->
-  <!-- =================================================================== -->
-  <target name="sampjar" depends="samples">
-    <jar jarfile="${build.dir}/${name}Samples.jar"
-         basedir="${build.dest}"
-         includes="dom/**,sax/**,ui/**,util/**"/>
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Prepares the docs                                                   -->
-  <!-- =================================================================== -->
-  <target name="prepare-docs" depends="init">
-    <mkdir dir="${build.docs}"/>
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Generate HTML docs                                                  -->
-  <!-- =================================================================== -->
-  <target name="docs" depends="prepare, prepare-docs">
-	<echo message="Building docs for ${Name} ${version} ..." />
-    <java fork="yes"
-          classpath="${java.class.path}:${doc.generator.package}"
-          classname="${doc.generator}"
-          args="targetDirectory=${build.docs} ${docs.book} ${doc.style}"/>
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Creates the API documentation                                       -->
-  <!-- =================================================================== -->
-  <target name="javadocs" depends="prepare-src">
-    <mkdir dir="${build.javadocs}"/>
-    <javadoc packagenames="${packages}"
-             sourcepath="${build.src}"
-             destdir="${build.javadocs}"
-             author="true"
-             version="true"
-             use="true"
-             windowtitle="${Name} API"
-             doctitle="${Name}"
-             bottom="${copyright}" />
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Prepares the source distribution                                    -->
-  <!-- =================================================================== -->
-  <target name="pack-src" depends="init">
-    <echo message="Building the source distribution files (zip,tar)"/>
-    <mkdir dir="${distsrc.dir}"/>
-    <mkdir dir="${distsrc.dir}/src"/>
-    <mkdir dir="${distsrc.dir}/data"/>
-    <mkdir dir="${distsrc.dir}/docs"/>
-    <mkdir dir="${distsrc.dir}/samples"/>
-
-    <copydir src="${src.dir}" dest="${distsrc.dir}/src" excludes="**/CVS*, **/.#*"
-             includes="**/Makefile, **/Makefile.incl, org/**, javax/**"/>
-    <copydir src="${data.dir}" dest="${distsrc.dir}/data" excludes="**/CVS*, **/.#*"/>
-    <copydir src="${docs.dir}" dest="${distsrc.dir}/docs"
-             excludes="**/CVS*, **/*.#*, pdf/**, html/**, **/apiDocs*"/>
-    <copydir src="${samples.dir}" dest="${distsrc.dir}/samples" excludes="**/CVS*, **/*.#*"/>
-
-    <copyfile src="LICENSE" dest="${distsrc.dir}/LICENSE"/>
-    <copyfile src="README" dest="${distsrc.dir}/README"/>
-    <copyfile src="Readme.html" dest="${distsrc.dir}/Readme.html"/>
-    <copyfile src="STATUS" dest="${distsrc.dir}/STATUS"/>
-    <copyfile src="build.xml" dest="${distsrc.dir}/build.xml"/>
-    <copyfile src="${basedir}/build.sh" dest="${distsrc.dir}/build.sh" />
-    <chmod src="${distsrc.dir}/build.sh" perm="ugo+rx" />
-    <copyfile src="${basedir}/build.bat" dest="${distsrc.dir}/build.bat" />
-
-    <zip zipfile="${build.dir}/${Name}-src${version_postfix}.zip" basedir="${build.dir}"
-         includes="${Name}-src${version_postfix}/**"/>
-    <tar tarfile="${build.dir}/${Name}-src${version_postfix}.tar" basedir="${build.dir}"
-         includes="${Name}-src${version_postfix}/**"/>
-    <gzip zipfile="${build.dir}/${Name}-src${version_postfix}.tar.gz"
-          src="${build.dir}/${Name}-src${version_postfix}.tar" />
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Prepares the binary distribution                                    -->
-  <!-- =================================================================== -->
-  <target name="pack-bin" depends="jar, sampjar, javadocs, docs">
-
-    <echo message="Building the binary distribution files (zip,tar)"/>
-    <mkdir dir="${distbin.dir}"/>
-    <mkdir dir="${distbin.dir}/data"/>
-    <mkdir dir="${distbin.dir}/docs"/>
-    <mkdir dir="${distbin.dir}/docs/html"/>
-    <mkdir dir="${distbin.dir}/docs/apiDocs"/>
-
-    <copydir src="${data.dir}" dest="${distbin.dir}/data" excludes="**/CVS*, **/*.#*"/>
-    <copydir src="${build.docs}" dest="${distbin.dir}/docs/html"/>
-    <copydir src="${build.javadocs}" dest="${distbin.dir}/docs/apiDocs"/>
-
-    <copyfile src="${build.dir}/${name}.jar" dest="${distbin.dir}/${name}.jar"/>
-    <copyfile src="${build.dir}/${name}Samples.jar" dest="${distbin.dir}/${name}Samples.jar"/>
-
-    <copyfile src="LICENSE" dest="${distbin.dir}/LICENSE"/>
-    <copyfile src="Readme.html" dest="${distbin.dir}/Readme.html"/>
-
-    <zip zipfile="${build.dir}/${Name}-bin${version_postfix}.zip" basedir="${build.dir}"
-         includes="${Name}-bin${version_postfix}/**"/>
-    <tar tarfile="${build.dir}/${Name}-bin${version_postfix}.tar" basedir="${build.dir}"
-         includes="${Name}-bin${version_postfix}/**"/>
-    <gzip zipfile="${build.dir}/${Name}-bin${version_postfix}.tar.gz"
-          src="${build.dir}/${Name}-bin${version_postfix}.tar" />
-
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Do a sanity test using xercesSamples.jar                            -->
-  <!-- =================================================================== -->
-  <target name="test" depends="sampjar">
-	<echo message="Performing sanity test for ${Name} ${version} ..." />
-	<echo message="Using classpath=&apos;${build.dir}/${name}Samples.jar;${build.dir}/${name}.jar&apos;" />
-	<echo message="Running SAXCount ..." />
-    <java fork="yes"
-          classpath="${build.dir}/${name}Samples.jar:${build.dir}/${name}.jar;"
-          classname="sax.SAXCount"
-          args="${data.dir}/personal.xml"/>
-	<echo message="Running SAX2Count ..." />
-    <java fork="yes"
-          classpath="${build.dir}/${name}Samples.jar:${build.dir}/${name}.jar;"
-          classname="sax.SAX2Count"
-          args="${data.dir}/personal.xml"/>
-	<echo message="Running SAXWriter ..." />
-    <java fork="yes"
-          classpath="${build.dir}/${name}Samples.jar:${build.dir}/${name}.jar"
-          classname="sax.SAXWriter"
-          args="${data.dir}/personal.xml"/>
-	<echo message="Running DOMCount ..." />
-    <java fork="yes"
-          classpath="${build.dir}/${name}Samples.jar:${build.dir}/${name}.jar"
-          classname="dom.DOMCount"
-          args="${data.dir}/personal.xml"/>
-	<echo message="Running DOMWriter ..." />
-    <java fork="yes"
-          classpath="${build.dir}/${name}Samples.jar:${build.dir}/${name}.jar"
-          classname="dom.DOMWriter"
-          args="${data.dir}/personal.xml"/>
-	<echo message="Running DOMFilter ..." />
-    <java fork="yes"
-          classpath="${build.dir}/${name}Samples.jar:${build.dir}/${name}.jar"
-          classname="dom.DOMFilter"
-          args="-p dom.wrappers.DOMParser ${data.dir}/personal.xml"/>
-    <!-- The following are samples but not command-line applications.
-	<echo message="Running IteratorView ..." />
-    <java fork="yes"
-          classpath="${build.dir}/${name}Samples.jar:${build.dir}/${name}.jar"
-          classname="dom.traversal.IteratorView"
-          args="${data.dir}/personal.xml"/>
-	<echo message="Running TreeWalkerView ..." />
-    <java fork="yes"
-          classpath="${build.dir}/${name}Samples.jar:${build.dir}/${name}.jar"
-          classname="dom.traversal.TreeWalkerView"
-          args="${data.dir}/personal.xml"/>
-	<echo message="Running TreeViewer ..." />
-    <java fork="yes"
-          classpath="${build.dir}/${name}Samples.jar:${build.dir}/${name}.jar"
-          classname="dom.TreeViewer"
-          args="${data.dir}/personal.xml"/>
-     -->
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Builds both xerces and sample jar files                             -->
-  <!-- =================================================================== -->
-  <target name="jars" depends="jar, sampjar">
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Builds and packages sources and binary distributions                -->
-  <!-- =================================================================== -->
-  <target name="all" depends="pack-src, pack-bin">
-  </target>
-
-  <!-- =================================================================== -->
-  <!-- Cleans everything                                                   -->
-  <!-- =================================================================== -->
-  <target name="clean" depends="init">
-    <delete file="${name}.jar"/>
-    <delete file="${name}Samples.jar"/>
-    <deltree dir="${build.dir}"/>
-  </target>
-
-</project>
diff --git a/data/personal-schema.xml b/data/personal-schema.xml
deleted file mode 100644
index d718ef1..0000000
--- a/data/personal-schema.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<personnel xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
-	   xsi:noNamespaceSchemaLocation='personal.xsd'>
-
-  <person id="Big.Boss" >
-    <name><family>Boss</family> <given>Big</given></name>
-    <email>chief@foo.com</email>
-    <link subordinates="one.worker two.worker three.worker four.worker five.worker"/>
-  </person>
-
-  <person id="one.worker">
-    <name><family>Worker</family> <given>One</given></name>
-    <email>one@foo.com</email>
-    <link manager="Big.Boss"/>
-  </person>
-
-  <person id="two.worker">
-    <name><family>Worker</family> <given>Two</given></name>
-    <email>two@foo.com</email>
-    <link manager="Big.Boss"/>
-  </person>
-
-  <person id="three.worker">
-    <name><family>Worker</family> <given>Three</given></name>
-    <email>three@foo.com</email>
-    <link manager="Big.Boss"/>
-  </person>
-
-  <person id="four.worker">
-    <name><family>Worker</family> <given>Four</given></name>
-    <email>four@foo.com</email>
-    <link manager="Big.Boss"/>
-  </person>
-
-  <person id="five.worker">
-    <name><family>Worker</family> <given>Five</given></name>
-    <email>five@foo.com</email>
-    <link manager="Big.Boss"/>
-  </person>
-
-</personnel>
diff --git a/data/personal.dtd b/data/personal.dtd
deleted file mode 100644
index c64e48a..0000000
--- a/data/personal.dtd
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml encoding="UTF-8"?>
-<!ELEMENT personnel (person)+>
-
-<!ELEMENT person (name,email*,url*,link?)>
-<!ATTLIST person id ID #REQUIRED>
-<!ATTLIST person note CDATA #IMPLIED>
-<!ATTLIST person contr (true|false) 'false'>
-<!ATTLIST person salary CDATA #IMPLIED>
-
-<!ELEMENT name ((family,given)|(given,family))>
-
-<!ELEMENT family (#PCDATA)>
-
-<!ELEMENT given (#PCDATA)>
-
-<!ELEMENT email (#PCDATA)>
-
-<!ELEMENT url EMPTY>
-<!ATTLIST url href CDATA 'http://'>
-
-<!ELEMENT link EMPTY>
-<!ATTLIST link manager IDREF #IMPLIED>
-<!ATTLIST link subordinates IDREFS #IMPLIED>
-
-<!NOTATION gif PUBLIC '-//APP/Photoshop/4.0' 'photoshop.exe'>
diff --git a/data/personal.xml b/data/personal.xml
deleted file mode 100644
index ad492e4..0000000
--- a/data/personal.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE personnel SYSTEM "personal.dtd">
-<personnel>
-
-  <person id="Big.Boss">
-    <name><family>Boss</family> <given>Big</given></name>
-    <email>chief@foo.com</email>
-    <link subordinates="one.worker two.worker three.worker four.worker five.worker"/>
-  </person>
-
-  <person id="one.worker">
-    <name><family>Worker</family> <given>One</given></name>
-    <email>one@foo.com</email>
-    <link manager="Big.Boss"/>
-  </person>
-
-  <person id="two.worker">
-    <name><family>Worker</family> <given>Two</given></name>
-    <email>two@foo.com</email>
-    <link manager="Big.Boss"/>
-  </person>
-
-  <person id="three.worker">
-    <name><family>Worker</family> <given>Three</given></name>
-    <email>three@foo.com</email>
-    <link manager="Big.Boss"/>
-  </person>
-
-  <person id="four.worker">
-    <name><family>Worker</family> <given>Four</given></name>
-    <email>four@foo.com</email>
-    <link manager="Big.Boss"/>
-  </person>
-
-  <person id="five.worker">
-    <name><family>Worker</family> <given>Five</given></name>
-    <email>five@foo.com</email>
-    <link manager="Big.Boss"/>
-  </person>
-
-</personnel>
diff --git a/data/personal.xsd b/data/personal.xsd
deleted file mode 100644
index d74b551..0000000
--- a/data/personal.xsd
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<schema>
-
- <element name="personnel">
-  <complexType>
-   <element ref="person" minOccurs='1' maxOccurs='unbounded'/>
-  </complexType>
- </element>
-
- <element name="person">
-  <complexType>
-   <element ref="name"/>
-   <element ref="email" minOccurs='0' maxOccurs='unbounded'/>
-   <element ref="url"   minOccurs='0' maxOccurs='unbounded'/>
-   <element ref="link"  minOccurs='0' maxOccurs='1'/>
-
-   <attribute name="id"  type="ID" use='required'/>
-   <attribute name="note" type="string"/>
-   <attribute name="contr" type="NMTOKEN" use='default' value="false">
-    <simpleType base="string">
-     <enumeration value="true"/>
-     <enumeration value="false"/>
-    </simpleType>
-   </attribute>
-   <attribute name="salary" type="integer"/>
-  </complexType>
- </element>
-
- <element name="name">
-  <complexType content='elementOnly'>
-   <all>
-    <element ref="family"/>
-    <element ref="given"/>
-   </all>
-  </complexType>
- </element>
-
- <element name="family" type='string'/>
-
- <element name="given" type='string'/>
-
- <element name="email" type='string'/>
-
- <element name="url">
-  <complexType content="empty">
-   <attribute name="href" type="string" default="http://"/>
-  </complexType>
- </element>
-
- <element name="link">
-  <complexType content="empty">
-   <attribute name="manager" type="IDREF"/>
-   <attribute name="subordinates" type="IDREFS"/>
-  </complexType>
- </element>
-
- <notation name='gif' public='-//APP/Photoshop/4.0' system='photoshop.exe'/>
-
-</schema>
diff --git a/docs/api.xml b/docs/api.xml
deleted file mode 100644
index 7f50478..0000000
--- a/docs/api.xml
+++ /dev/null
@@ -1,149 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="API Documentation">
-    <s2 title="Javadoc Generated Documentation">
-        <p>&javaparsernamelong; comes packaged with API documentation for SAX and DOM, 
-        the two most common interfaces for programming XML.  In addition, 
-        we provide documentation for classes that are not part of the SAX 
-        and DOM API's, but are useful for writing &javaparsername; programs. </p>
-        <p>This documentation is generated automatically from the Javadoc-style 
-        comments inside the source files.  Click on one of the links below to 
-        go to the appropriate API documentation.</p>
-    </s2>
-    <s2 title="&javaparsername; API Documentation">
-        <ul>
-            <li><jump href="../apiDocs/index.html">Full API documentation</jump></li>
-            <li><jump href="../apiDocs/overview-tree.html">Hierarchy for all the packages</jump></li>
-        </ul>
-    <s3 title="Package org.apache.xerces.parsers">
-      <s4 title="Classes">
-        <ul>
-            <li>DOMParser</li>
-            <li>SAXParser</li>
-        </ul>
-      </s4>
-      <s4 title="Interfaces">
-        <ul>
-            <li>Attr
-                <br/>The Attr interface represents an attribute in an Element object</li>
-            <li>CDATASection
-                <br/>CDATA sections are used to escape blocks of text containing characters
-                that would otherwise be regarded as markup</li>
-            <li>CharacterData
-                <br/>The CharacterData interface extends Node with a set of attributes and
-                methods for accessing character data in the DOM</li>
-            <li>Comment
-                <br/>This represents the content of a comment</li>
-            <li>Document
-                <br/>The Document interface represents the entire HTML or XML document</li>
-            <li>DocumentFragment
-                <br/>DocumentFragment is a "lightweight" or "minimal" Document object</li>
-            <li>DocumentType
-                <br/>Each Document has a doctype attribute whose value is either null or a
-                DocumentType object</li>
-            <li>DOMImplementation
-                <br/>The DOMImplementation interface provides  methods for performing
-                operations independent of a particular document object model instance</li>
-            <li>Element
-                <br/>The majority of objects (apart from text) in a document are Element nodes</li>
-            <li>Entity
-                <br/>This interface represents an entity, either parsed or unparsed, in a XML
-                document</li>
-            <li>EntityReference
-                <br/>EntityReference objects may be inserted into the structure model</li>
-            <li>NamedNodeMap
-                <br/>Objects implementing the NamedNodeMap interface are used to represent
-                collections of nodes that can be accessed by name</li>
-            <li>Node
-                <br/>The Node interface is the primary datatype for the entire Document Object
-                Model</li>
-            <li>NodeList
-                <br/>The NodeList interface provides the abstraction of an ordered collection
-                of nodes</li>
-            <li>Notation
-                <br/>This interface represents a notation declared in the DTD</li>
-            <li>ProcessingInstruction
-                <br/>The ProcessingInstruction is a way to keep processor-specific
-                information in the text of the document</li>
-            <li>Text
-                <br/>The Text interface represents the textual content (termed character data in
-                XML) of an Element or Attr</li>
-        </ul>
-      </s4>
-      <s4 title="Exceptions">
-        <ul>
-            <li>DOMException
-            <br/>Encapsulate an "exceptional" DOM error </li>
-        </ul>
-      </s4>
-    </s3>
-    <s3 title="Package org.xml.sax">
-      <s4 title="Classes">
-        <ul>
-            <li>HandlerBase
-                <br/>Default base class for handlers</li>
-            <li>InputSource
-                <br/>A single input source for an XML entity </li>
-        </ul>
-      </s4>
-      <s4 title="Interfaces">
-        <ul>
-            <li>AttributeList
-                <br/>Interface for an element's attribute specifications</li>
-            <li>DocumentHandler
-                <br/>Receive notification of general document events</li>
-            <li>DTDHandler
-                <br/>Receive notification of basic DTD-related events</li>
-            <li>EntityResolver
-                <br/>Basic interface for resolving entities</li>
-            <li>ErrorHandler
-                <br/>Basic interface for SAX error handlers </li>
-            <li>Locator
-                <br/>Interface for associating a SAX event with a document location</li>
-            <li>Parser
-                <br/>Basic interface for SAX (Simple API for XML) parsers</li>
-        </ul>
-      </s4>
-      <s4 title="Exceptions">
-        <ul>
-            <li>SAXException
-                <br/>Encapsulate a general SAX error or warning</li>
-            <li>SAXParseException
-                <br/>Encapsulate an XML parse error or warning </li>
-        </ul>
-      </s4>
-    </s3>
-    <s3 title="Package org.xml.sax.helpers">
-      <s4 title="Classes">
-        <ul>
-            <li>AttributeListImpl
-                <br/>Convenience implementation for AttributeList</li>
-            <li>LocatorImpl
-                <br/>Convenience implementation for Locator</li>
-            <li>ParserFactory
-                <br/>Java-specific class for dynamically loading SAX parsers</li>
-        </ul>
-      </s4>
-   </s3>
-    <s3 title="Package org.apache.xerces.dom.traversal">
-      <s4 title="Classes">
-        <ul>
-            <li>DocumentTraversal
-                <br/>DocumentTraversal contains methods that creates Iterators to traverse a
-                node and its children</li>
-            <li>DocumentTWIF
-                <br/>DocumentTWIF contains methods that create Iterators to traverse a node
-                and its children</li>
-            <li>NodeFilter
-                <br/>Filters are objects that know how to "filter out" nodes</li>
-            <li>NodeIterator
-                <br/>NodeIterators are used to step through a set of nodes</li>
-            <li>TreeWalker
-                <br/>TreeWalker objects are used to navigate a document tree or subtree using
-                the view of the document </li>
-        </ul>
-      </s4>
-    </s3>
-  </s2>
-</s1>
diff --git a/docs/caveats.xml b/docs/caveats.xml
deleted file mode 100644
index 031e1d0..0000000
--- a/docs/caveats.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="Caveats">
-	<s2 title="Caveats and Limitations">
-		<p>This is a list of the limitations in this release of &javaparsername;:</p>
-		<ul>
-			<li>Due to a transcoding bug in the Sun JDK's 
-			(1.1.6, 1.1.7, 1.1.8, 1.2)  handling of EBCDIC data 
-			(specifically, end of line characters), you must use 
-			IBM's JDK 1.1.6, if you want to use EBCDIC support. 
-			The IBM JDK has the bug fixed.  We don't know when the 
-			bug fix will get into the Sun JDK's. </li>
-		</ul>
-	</s2>
-</s1>
diff --git a/docs/docs-book.xml b/docs/docs-book.xml
deleted file mode 100644
index 3ed79ca..0000000
--- a/docs/docs-book.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE book SYSTEM "./dtd/book.dtd">
-
-<book title="Xerces-J Documentation" copyright="1999, 2000 The Apache Software Foundation">
-  <external href="../index.html"  label="Home"/>
-
-  <separator/>
-  <document id="index"       label="Readme"       source="readme.xml"      />
-  <external href="http://xml.apache.org/dist/xerces-j/"  label="Download"/>
-  <document id="install"     label="Installation" source="install.xml"     />
-
-  <separator/>
-  <document id="api"         label="API Docs"     source="api.xml"         />
-  <!--
-  <container id="samples"     label="Samples"      source="samples.xml">
-	<entry  id="domcount"        source="sam-domcount.xml" />
-	<entry  id="domwriter"       source="sam-domwriter.xml"/>
-	<entry  id="domfilter"       source="sam-domfilter.xml"/>
-	<entry  id="iterator"        source="sam-iterator.xml" />
-	<entry  id="tree"            source="sam-tree.xml"     />
-	<entry  id="treeview"        source="sam-treeview.xml" />
-  </container>
-  -->
-  <document id='samples'     label='Samples'      source='samples.xml'/>
-  <hidden id='domcount' source='sam-domcount.xml'/>
-  <hidden id="domwriter"       source="sam-domwriter.xml"/>
-  <hidden id="domfilter"       source="sam-domfilter.xml"/>
-  <hidden id="iterator"        source="sam-iterator.xml" />
-  <hidden  id="tree"            source="sam-tree.xml"     />
-  <hidden  id="treeview"        source="sam-treeview.xml" />
-  <document id="schema"      label="Schema"       source="schema.xml"      />
-
-  <separator/>
-  <document id="properties"  label="Properties"   source="properties.xml"  />
-  <document id="features"    label="Features"     source="features.xml"    />
-  <group    id="faqs"        title="Frequently Asked Questions" label="FAQs">
-    <entry  id="faq-general"                      source="faq-general.xml" />
-    <entry  id="faq-build"                        source="faq-build.xml"   />
-    <entry  id="faq-write"                        source="faq-write.xml"   />
-    <entry  id="faq-performance"                  source="faq-performance.xml"   />
-    <entry  id="faq-migrate"                      source="faq-migrate.xml" />
-    <entry  id="faq-common"                       source="faq-common.xml"  />
-  </group>
-	<hidden   id="jpc"       	  source="javapurecheck.xml"/>
-
-  <separator/>
-  <document id="releases"    label="Releases"     source="releases.xml"    />
-  <document id="caveats"     label="Caveats"      source="caveats.xml"     />
-  <document id="feedback"    label="Feedback"     source="feedback.xml"    />
-
-  <separator/>
-  <document id="y2k"         label="Y2K Compliance" source="y2k.xml"       />
-</book>
diff --git a/docs/dtd/blocks.ent b/docs/dtd/blocks.ent
deleted file mode 100644
index 16114e7..0000000
--- a/docs/dtd/blocks.ent
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml encoding='US-ASCII'?>
-
-<!-- BLOCKS ENTITY -->
-<!ENTITY % blocks "p|note|ul|ol|gloss|table|source|anchor">
-
-<!-- import the external markup.ent dtd -->
-<!ENTITY % markupEntity SYSTEM "markup.ent">
-%markupEntity;
-
-<!ENTITY % content "(#PCDATA|%markup;|%links;)*">
-
-<!ELEMENT p %content;>
-<!ELEMENT note %content;>
-
-<!ELEMENT ul (li|ol|ul)+>
-<!ELEMENT ol (li|ol|ul)+>
-<!ELEMENT li %content;>
-
-<!ELEMENT gloss (label|item)+>
-<!ELEMENT label %content;>
-<!ELEMENT item %content;>
-
-<!ELEMENT source (#PCDATA)>
-
-<!ELEMENT table (tr)+>
-
-<!ELEMENT tr (tn|th|td)+>
-
-<!ELEMENT tn EMPTY>
-<!ATTLIST tn colspan CDATA "1"
-             rowspan CDATA "1">
-
-<!ELEMENT th %content;>
-<!ATTLIST th colspan CDATA "1"
-             rowspan CDATA "1">
-
-<!ELEMENT td %content;>
-<!ATTLIST td colspan CDATA "1"
-             rowspan CDATA "1">
-             
\ No newline at end of file
diff --git a/docs/dtd/book.dtd b/docs/dtd/book.dtd
deleted file mode 100644
index 1a2e570..0000000
--- a/docs/dtd/book.dtd
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml encoding='US-ASCII'?>
-
-<!-- STYLEBOOK BOOK DTD -->
-
-<!-- import the external source-specific dtd -->
-<!ENTITY % externalEntity SYSTEM "entities.ent">
-%externalEntity;
-
-<!ELEMENT book (resources?|document|hidden|faqs|changes|group|container|external|separator)+>
-<!ATTLIST book title     CDATA #REQUIRED
-               copyright CDATA #IMPLIED>
-               
-<!ELEMENT resources EMPTY>
-<!ATTLIST resources source CDATA #REQUIRED>
-
-<!ELEMENT document EMPTY>
-<!ATTLIST document id     ID    #REQUIRED
-                   source CDATA #REQUIRED
-                   label  CDATA #REQUIRED>
-
-<!ELEMENT hidden EMPTY>
-<!ATTLIST hidden id     ID    #REQUIRED
-                 source CDATA #REQUIRED>
-
-<!ELEMENT faqs EMPTY>
-<!ATTLIST faqs id     ID    #REQUIRED
-               source CDATA #REQUIRED
-               label  CDATA #REQUIRED>
-
-<!ELEMENT changes EMPTY>
-<!ATTLIST changes id     ID    #REQUIRED
-                  source CDATA #REQUIRED
-                  label  CDATA #REQUIRED>
-
-<!ELEMENT group (entry)+>
-<!ATTLIST group id    ID    #IMPLIED
-		label CDATA #REQUIRED                
-		title CDATA #REQUIRED>
-
-<!ELEMENT container (entry)+>
-<!ATTLIST container id    ID    #IMPLIED
-	            source CDATA #REQUIRED
-               	    label CDATA #REQUIRED>
-
-<!ELEMENT entry EMPTY>
-<!ATTLIST entry id     ID    #REQUIRED
-                source CDATA #REQUIRED>
-
-<!ELEMENT external EMPTY>
-<!ATTLIST external label CDATA #REQUIRED
-                   href  CDATA #REQUIRED>
-                   
-<!ELEMENT separator EMPTY>
-
-<!-- CVS $Revision$ $Date$ -->
diff --git a/docs/dtd/characters.ent b/docs/dtd/characters.ent
deleted file mode 100644
index 019fb6e..0000000
--- a/docs/dtd/characters.ent
+++ /dev/null
@@ -1,297 +0,0 @@
-<?xml encoding='US-ASCII'?>
-
-<!-- CHARACTERS ENTITY -->
-
-<!-- Latin A -->
-<!ENTITY nbsp     "&#160;">  <!-- U+00A0 ISOnum    - no-break space = non-breaking space                                   -->
-<!ENTITY iexcl    "&#161;">  <!-- U+00A1 ISOnum    - inverted exclamation mark                                             -->
-<!ENTITY cent     "&#162;">  <!-- U+00A2 ISOnum    - cent sign                                                             -->
-<!ENTITY pound    "&#163;">  <!-- U+00A3 ISOnum    - pound sign                                                            -->
-<!ENTITY curren   "&#164;">  <!-- U+00A4 ISOnum    - currency sign                                                         -->
-<!ENTITY yen      "&#165;">  <!-- U+00A5 ISOnum    - yen sign = yuan sign                                                  -->
-<!ENTITY brvbar   "&#166;">  <!-- U+00A6 ISOnum    - broken bar = broken vertical bar                                      -->
-<!ENTITY sect     "&#167;">  <!-- U+00A7 ISOnum    - section sign                                                          -->
-<!ENTITY uml      "&#168;">  <!-- U+00A8 ISOdia    - diaeresis = spacing diaeresis                                         -->
-<!ENTITY copy     "&#169;">  <!-- U+00A9 ISOnum    - copyright sign                                                        -->
-<!ENTITY ordf     "&#170;">  <!-- U+00AA ISOnum    - feminine ordinal indicator                                            -->
-<!ENTITY laquo    "&#171;">  <!-- U+00AB ISOnum    - left-pointing double angle quotation mark = left pointing guillemet   -->
-<!ENTITY not      "&#172;">  <!-- U+00AC ISOnum    - not sign                                                              -->
-<!ENTITY shy      "&#173;">  <!-- U+00AD ISOnum    - soft hyphen = discretionary hyphen                                    -->
-<!ENTITY reg      "&#174;">  <!-- U+00AE ISOnum    - registered sign = registered trade mark sign                          -->
-<!ENTITY macr     "&#175;">  <!-- U+00AF ISOdia    - macron = spacing macron = overline = APL overbar                      -->
-<!ENTITY deg      "&#176;">  <!-- U+00B0 ISOnum    - degree sign                                                           -->
-<!ENTITY plusmn   "&#177;">  <!-- U+00B1 ISOnum    - plus-minus sign = plus-or-minus sign                                  -->
-<!ENTITY sup2     "&#178;">  <!-- U+00B2 ISOnum    - superscript two = superscript digit two = squared                     -->
-<!ENTITY sup3     "&#179;">  <!-- U+00B3 ISOnum    - superscript three = superscript digit three = cubed                   -->
-<!ENTITY acute    "&#180;">  <!-- U+00B4 ISOdia    - acute accent = spacing acute                                          -->
-<!ENTITY micro    "&#181;">  <!-- U+00B5 ISOnum    - micro sign                                                            -->
-<!ENTITY para     "&#182;">  <!-- U+00B6 ISOnum    - pilcrow sign = paragraph sign                                         -->
-<!ENTITY middot   "&#183;">  <!-- U+00B7 ISOnum    - middle dot = Georgian comma = Greek middle dot                        -->
-<!ENTITY cedil    "&#184;">  <!-- U+00B8 ISOdia    - cedilla = spacing cedilla                                             -->
-<!ENTITY sup1     "&#185;">  <!-- U+00B9 ISOnum    - superscript one = superscript digit one                               -->
-<!ENTITY ordm     "&#186;">  <!-- U+00BA ISOnum    - masculine ordinal indicator                                           -->
-<!ENTITY raquo    "&#187;">  <!-- U+00BB ISOnum    - right-pointing double angle quotation mark = right pointing guillemet -->
-<!ENTITY frac14   "&#188;">  <!-- U+00BC ISOnum    - vulgar fraction one quarter = fraction one quarter                    -->
-<!ENTITY frac12   "&#189;">  <!-- U+00BD ISOnum    - vulgar fraction one half = fraction one half                          -->
-<!ENTITY frac34   "&#190;">  <!-- U+00BE ISOnum    - vulgar fraction three quarters = fraction three quarters              -->
-<!ENTITY iquest   "&#191;">  <!-- U+00BF ISOnum    - inverted question mark = turned question mark                         -->
-<!ENTITY Agrave   "&#192;">  <!-- U+00C0 ISOlat1   - latin capital letter A with grave = latin capital letter A grave      -->
-<!ENTITY Aacute   "&#193;">  <!-- U+00C1 ISOlat1   - latin capital letter A with acute                                     -->
-<!ENTITY Acirc    "&#194;">  <!-- U+00C2 ISOlat1   - latin capital letter A with circumflex                                -->
-<!ENTITY Atilde   "&#195;">  <!-- U+00C3 ISOlat1   - latin capital letter A with tilde                                     -->
-<!ENTITY Auml     "&#196;">  <!-- U+00C4 ISOlat1   - latin capital letter A with diaeresis                                 -->
-<!ENTITY Aring    "&#197;">  <!-- U+00C5 ISOlat1   - latin capital letter A with ring above = latin capital letter A ring  -->
-<!ENTITY AElig    "&#198;">  <!-- U+00C6 ISOlat1   - latin capital letter AE = latin capital ligature AE                   -->
-<!ENTITY Ccedil   "&#199;">  <!-- U+00C7 ISOlat1   - latin capital letter C with cedilla                                   -->
-<!ENTITY Egrave   "&#200;">  <!-- U+00C8 ISOlat1   - latin capital letter E with grave                                     -->
-<!ENTITY Eacute   "&#201;">  <!-- U+00C9 ISOlat1   - latin capital letter E with acute                                     -->
-<!ENTITY Ecirc    "&#202;">  <!-- U+00CA ISOlat1   - latin capital letter E with circumflex                                -->
-<!ENTITY Euml     "&#203;">  <!-- U+00CB ISOlat1   - latin capital letter E with diaeresis                                 -->
-<!ENTITY Igrave   "&#204;">  <!-- U+00CC ISOlat1   - latin capital letter I with grave                                     -->
-<!ENTITY Iacute   "&#205;">  <!-- U+00CD ISOlat1   - latin capital letter I with acute                                     -->
-<!ENTITY Icirc    "&#206;">  <!-- U+00CE ISOlat1   - latin capital letter I with circumflex                                -->
-<!ENTITY Iuml     "&#207;">  <!-- U+00CF ISOlat1   - latin capital letter I with diaeresis                                 -->
-<!ENTITY ETH      "&#208;">  <!-- U+00D0 ISOlat1   - latin capital letter ETH                                              -->
-<!ENTITY Ntilde   "&#209;">  <!-- U+00D1 ISOlat1   - latin capital letter N with tilde                                     -->
-<!ENTITY Ograve   "&#210;">  <!-- U+00D2 ISOlat1   - latin capital letter O with grave                                     -->
-<!ENTITY Oacute   "&#211;">  <!-- U+00D3 ISOlat1   - latin capital letter O with acute                                     -->
-<!ENTITY Ocirc    "&#212;">  <!-- U+00D4 ISOlat1   - latin capital letter O with circumflex                                -->
-<!ENTITY Otilde   "&#213;">  <!-- U+00D5 ISOlat1   - latin capital letter O with tilde                                     -->
-<!ENTITY Ouml     "&#214;">  <!-- U+00D6 ISOlat1   - latin capital letter O with diaeresis                                 -->
-<!ENTITY times    "&#215;">  <!-- U+00D7 ISOnum    - multiplication sign                                                   -->
-<!ENTITY Oslash   "&#216;">  <!-- U+00D8 ISOlat1   - latin capital letter O with stroke = latin capital letter O slash     -->
-<!ENTITY Ugrave   "&#217;">  <!-- U+00D9 ISOlat1   - latin capital letter U with grave                                     -->
-<!ENTITY Uacute   "&#218;">  <!-- U+00DA ISOlat1   - latin capital letter U with acute                                     -->
-<!ENTITY Ucirc    "&#219;">  <!-- U+00DB ISOlat1   - latin capital letter U with circumflex                                -->
-<!ENTITY Uuml     "&#220;">  <!-- U+00DC ISOlat1   - latin capital letter U with diaeresis                                 -->
-<!ENTITY Yacute   "&#221;">  <!-- U+00DD ISOlat1   - latin capital letter Y with acute                                     -->
-<!ENTITY THORN    "&#222;">  <!-- U+00DE ISOlat1   - latin capital letter THORN                                            -->
-<!ENTITY szlig    "&#223;">  <!-- U+00DF ISOlat1   - latin small letter sharp s = ess-zed                                  -->
-<!ENTITY agrave   "&#224;">  <!-- U+00E0 ISOlat1   - latin small letter a with grave = latin small letter a grave          -->
-<!ENTITY aacute   "&#225;">  <!-- U+00E1 ISOlat1   - latin small letter a with acute                                       -->
-<!ENTITY acirc    "&#226;">  <!-- U+00E2 ISOlat1   - latin small letter a with circumflex                                  -->
-<!ENTITY atilde   "&#227;">  <!-- U+00E3 ISOlat1   - latin small letter a with tilde                                       -->
-<!ENTITY auml     "&#228;">  <!-- U+00E4 ISOlat1   - latin small letter a with diaeresis                                   -->
-<!ENTITY aring    "&#229;">  <!-- U+00E5 ISOlat1   - latin small letter a with ring above = latin small letter a ring      -->
-<!ENTITY aelig    "&#230;">  <!-- U+00E6 ISOlat1   - latin small letter ae = latin small ligature ae                       -->
-<!ENTITY ccedil   "&#231;">  <!-- U+00E7 ISOlat1   - latin small letter c with cedilla                                     -->
-<!ENTITY egrave   "&#232;">  <!-- U+00E8 ISOlat1   - latin small letter e with grave                                       -->
-<!ENTITY eacute   "&#233;">  <!-- U+00E9 ISOlat1   - latin small letter e with acute                                       -->
-<!ENTITY ecirc    "&#234;">  <!-- U+00EA ISOlat1   - latin small letter e with circumflex                                  -->
-<!ENTITY euml     "&#235;">  <!-- U+00EB ISOlat1   - latin small letter e with diaeresis                                   -->
-<!ENTITY igrave   "&#236;">  <!-- U+00EC ISOlat1   - latin small letter i with grave                                       -->
-<!ENTITY iacute   "&#237;">  <!-- U+00ED ISOlat1   - latin small letter i with acute                                       -->
-<!ENTITY icirc    "&#238;">  <!-- U+00EE ISOlat1   - latin small letter i with circumflex                                  -->
-<!ENTITY iuml     "&#239;">  <!-- U+00EF ISOlat1   - latin small letter i with diaeresis                                   -->
-<!ENTITY eth      "&#240;">  <!-- U+00F0 ISOlat1   - latin small letter eth                                                -->
-<!ENTITY ntilde   "&#241;">  <!-- U+00F1 ISOlat1   - latin small letter n with tilde                                       -->
-<!ENTITY ograve   "&#242;">  <!-- U+00F2 ISOlat1   - latin small letter o with grave                                       -->
-<!ENTITY oacute   "&#243;">  <!-- U+00F3 ISOlat1   - latin small letter o with acute                                       -->
-<!ENTITY ocirc    "&#244;">  <!-- U+00F4 ISOlat1   - latin small letter o with circumflex                                  -->
-<!ENTITY otilde   "&#245;">  <!-- U+00F5 ISOlat1   - latin small letter o with tilde                                       -->
-<!ENTITY ouml     "&#246;">  <!-- U+00F6 ISOlat1   - latin small letter o with diaeresis                                   -->
-<!ENTITY divide   "&#247;">  <!-- U+00F7 ISOnum    - division sign                                                         -->
-<!ENTITY oslash   "&#248;">  <!-- U+00F8 ISOlat1   - latin small letter o with stroke = latin small letter o slash         -->
-<!ENTITY ugrave   "&#249;">  <!-- U+00F9 ISOlat1   - latin small letter u with grave                                       -->
-<!ENTITY uacute   "&#250;">  <!-- U+00FA ISOlat1   - latin small letter u with acute                                       -->
-<!ENTITY ucirc    "&#251;">  <!-- U+00FB ISOlat1   - latin small letter u with circumflex                                  -->
-<!ENTITY uuml     "&#252;">  <!-- U+00FC ISOlat1   - latin small letter u with diaeresis                                   -->
-<!ENTITY yacute   "&#253;">  <!-- U+00FD ISOlat1   - latin small letter y with acute                                       -->
-<!ENTITY thorn    "&#254;">  <!-- U+00FE ISOlat1   - latin small letter thorn                                              -->
-<!ENTITY yuml     "&#255;">  <!-- U+00FF ISOlat1   - latin small letter y with diaeresis                                   -->
-
-
-<!-- C0 Controls and Basic Latin -->
-<!ENTITY quot     "&#34;">   <!-- U+0022 ISOnum    - quotation mark = APL quote                                            -->
-<!ENTITY amp      "&#38;">   <!-- U+0026 ISOnum    - ampersand                                                             -->
-<!ENTITY lt       "&#60;">   <!-- U+003C ISOnum    - less-than sign                                                        -->
-<!ENTITY gt       "&#62;">   <!-- U+003E ISOnum    - greater-than sign                                                     -->
-
-<!-- Latin Extended-A -->
-<!ENTITY OElig    "&#338;">  <!-- U+0152 ISOlat2   - latin capital ligature OE                                             -->
-<!ENTITY oelig    "&#339;">  <!-- U+0153 ISOlat2   - latin small ligature oe                                               -->
-
-<!-- ligature is a misnomer, this is a separate character in some languages -->
-<!ENTITY Scaron   "&#352;">  <!-- U+0160 ISOlat2   - latin capital letter S with caron                                     -->
-<!ENTITY scaron   "&#353;">  <!-- U+0161 ISOlat2   - latin small letter s with caron                                       -->
-<!ENTITY Yuml     "&#376;">  <!-- U+0178 ISOlat2   - latin capital letter Y with diaeresis                                 -->
-
-<!-- Spacing Modifier Letters -->
-<!ENTITY circ     "&#710;" > <!-- U+02C6 ISOpub    - modifier letter circumflex accent                                     -->
-<!ENTITY tilde    "&#732;" > <!-- U+02DC ISOdia    - small tilde                                                           -->
-
-<!-- General Punctuation -->
-<!ENTITY ensp     "&#8194;"> <!-- U+2002 ISOpub    - en space                                                              -->
-<!ENTITY emsp     "&#8195;"> <!-- U+2003 ISOpub    - em space                                                              -->
-<!ENTITY thinsp   "&#8201;"> <!-- U+2009 ISOpub    - thin space                                                            -->
-<!ENTITY zwnj     "&#8204;"> <!-- U+200C RFC 2070  - zero width non-joiner                                                 -->
-<!ENTITY zwj      "&#8205;"> <!-- U+200D RFC 2070  - zero width joiner                                                     -->
-<!ENTITY lrm      "&#8206;"> <!-- U+200E RFC 2070  - left-to-right mark                                                    -->
-<!ENTITY rlm      "&#8207;"> <!-- U+200F RFC 2070  - right-to-left mark                                                    -->
-<!ENTITY ndash    "&#8211;"> <!-- U+2013 ISOpub    - en dash                                                               -->
-<!ENTITY mdash    "&#8212;"> <!-- U+2014 ISOpub    - em dash                                                               -->
-<!ENTITY lsquo    "&#8216;"> <!-- U+2018 ISOnum    - left single quotation mark                                            -->
-<!ENTITY rsquo    "&#8217;"> <!-- U+2019 ISOnum    - right single quotation mark                                           -->
-<!ENTITY sbquo    "&#8218;"> <!-- U+201A NEW       - single low-9 quotation mark                                           -->
-<!ENTITY ldquo    "&#8220;"> <!-- U+201C ISOnum    - left double quotation mark                                            -->
-<!ENTITY rdquo    "&#8221;"> <!-- U+201D ISOnum    - right double quotation mark,                                          -->
-<!ENTITY bdquo    "&#8222;"> <!-- U+201E NEW       - double low-9 quotation mark                                           -->
-<!ENTITY dagger   "&#8224;"> <!-- U+2020 ISOpub    - dagger                                                                -->
-<!ENTITY Dagger   "&#8225;"> <!-- U+2021 ISOpub    - double dagger                                                         -->
-<!ENTITY permil   "&#8240;"> <!-- U+2030 ISOtech   - per mille sign                                                        -->
-<!ENTITY lsaquo   "&#8249;"> <!-- U+2039 ISO prop. - single left-pointing angle quotation mark                             -->
-
-<!-- lsaquo is proposed but not yet ISO standardized -->
-<!ENTITY rsaquo   "&#8250;"> <!-- U+203A ISO prop. -   single right-pointing angle quotation mark                          -->
-
-<!-- rsaquo is proposed but not yet ISO standardized -->
-<!ENTITY euro     "&#8364;"> <!-- U+20AC NEW       -   euro sign                                                           -->
-
-<!-- Latin Extended-B -->
-<!ENTITY fnof     "&#402;">  <!-- U+0192 ISOtech   - latin small f with hook = function = florin                           -->
-
-<!-- Greek -->
-<!ENTITY Alpha    "&#913;">  <!-- U+0391           - greek capital letter alpha                                            -->
-<!ENTITY Beta     "&#914;">  <!-- U+0392           - greek capital letter beta                                             -->
-<!ENTITY Gamma    "&#915;">  <!-- U+0393 ISOgrk3   - greek capital letter gamma                                            -->
-<!ENTITY Delta    "&#916;">  <!-- U+0394 ISOgrk3   - greek capital letter delta                                            -->
-<!ENTITY Epsilon  "&#917;">  <!-- U+0395           - greek capital letter epsilon                                          -->
-<!ENTITY Zeta     "&#918;">  <!-- U+0396           - greek capital letter zeta                                             -->
-<!ENTITY Eta      "&#919;">  <!-- U+0397           - greek capital letter eta                                              -->
-<!ENTITY Theta    "&#920;">  <!-- U+0398 ISOgrk3   - greek capital letter theta                                            -->
-<!ENTITY Iota     "&#921;">  <!-- U+0399           - greek capital letter iota                                             -->
-<!ENTITY Kappa    "&#922;">  <!-- U+039A           - greek capital letter kappa                                            -->
-<!ENTITY Lambda   "&#923;">  <!-- U+039B ISOgrk3   - greek capital letter lambda                                           -->
-<!ENTITY Mu       "&#924;">  <!-- U+039C           - greek capital letter mu                                               -->
-<!ENTITY Nu       "&#925;">  <!-- U+039D           - greek capital letter nu                                               -->
-<!ENTITY Xi       "&#926;">  <!-- U+039E ISOgrk3   - greek capital letter xi                                               -->
-<!ENTITY Omicron  "&#927;">  <!-- U+039F           - greek capital letter omicron                                          -->
-<!ENTITY Pi       "&#928;">  <!-- U+03A0 ISOgrk3   - greek capital letter pi                                               -->
-<!ENTITY Rho      "&#929;">  <!-- U+03A1           - greek capital letter rho                                              -->
-<!ENTITY Sigma    "&#931;">  <!-- U+03A3 ISOgrk3   - greek capital letter sigma                                            -->
-<!ENTITY Tau      "&#932;">  <!-- U+03A4           - greek capital letter tau                                              -->
-<!ENTITY Upsilon  "&#933;">  <!-- U+03A5 ISOgrk3   - greek capital letter upsilon                                          -->
-<!ENTITY Phi      "&#934;">  <!-- U+03A6 ISOgrk3   - greek capital letter phi                                              -->
-<!ENTITY Chi      "&#935;">  <!-- U+03A7           - greek capital letter chi                                              -->
-<!ENTITY Psi      "&#936;">  <!-- U+03A8 ISOgrk3   - greek capital letter psi                                              -->
-<!ENTITY Omega    "&#937;">  <!-- U+03A9 ISOgrk3   - greek capital letter omega                                            -->
-<!ENTITY alpha    "&#945;">  <!-- U+03B1 ISOgrk3   - greek small letter alpha                                              -->
-<!ENTITY beta     "&#946;">  <!-- U+03B2 ISOgrk3   - greek small letter beta                                               -->
-<!ENTITY gamma    "&#947;">  <!-- U+03B3 ISOgrk3   - greek small letter gamma                                              -->
-<!ENTITY delta    "&#948;">  <!-- U+03B4 ISOgrk3   - greek small letter delta                                              -->
-<!ENTITY epsilon  "&#949;">  <!-- U+03B5 ISOgrk3   - greek small letter epsilon                                            -->
-<!ENTITY zeta     "&#950;">  <!-- U+03B6 ISOgrk3   - greek small letter zeta                                               -->
-<!ENTITY eta      "&#951;">  <!-- U+03B7 ISOgrk3   - greek small letter eta                                                -->
-<!ENTITY theta    "&#952;">  <!-- U+03B8 ISOgrk3   - greek small letter theta                                              -->
-<!ENTITY iota     "&#953;">  <!-- U+03B9 ISOgrk3   - greek small letter iota                                               -->
-<!ENTITY kappa    "&#954;">  <!-- U+03BA ISOgrk3   - greek small letter kappa                                              -->
-<!ENTITY lambda   "&#955;">  <!-- U+03BB ISOgrk3   - greek small letter lambda                                             -->
-<!ENTITY mu       "&#956;">  <!-- U+03BC ISOgrk3   - greek small letter mu                                                 -->
-<!ENTITY nu       "&#957;">  <!-- U+03BD ISOgrk3   - greek small letter nu                                                 -->
-<!ENTITY xi       "&#958;">  <!-- U+03BE ISOgrk3   - greek small letter xi                                                 -->
-<!ENTITY omicron  "&#959;">  <!-- U+03BF NEW       - greek small letter omicron                                            -->
-<!ENTITY pi       "&#960;">  <!-- U+03C0 ISOgrk3   - greek small letter pi                                                 -->
-<!ENTITY rho      "&#961;">  <!-- U+03C1 ISOgrk3   - greek small letter rho                                                -->
-<!ENTITY sigmaf   "&#962;">  <!-- U+03C2 ISOgrk3   - greek small letter final sigma                                        -->
-<!ENTITY sigma    "&#963;">  <!-- U+03C3 ISOgrk3   - greek small letter sigma                                              -->
-<!ENTITY tau      "&#964;">  <!-- U+03C4 ISOgrk3   - greek small letter tau                                                -->
-<!ENTITY upsilon  "&#965;">  <!-- U+03C5 ISOgrk3   - greek small letter upsilon                                            -->
-<!ENTITY phi      "&#966;">  <!-- U+03C6 ISOgrk3   - greek small letter phi                                                -->
-<!ENTITY chi      "&#967;">  <!-- U+03C7 ISOgrk3   - greek small letter chi                                                -->
-<!ENTITY psi      "&#968;">  <!-- U+03C8 ISOgrk3   - greek small letter psi                                                -->
-<!ENTITY omega    "&#969;">  <!-- U+03C9 ISOgrk3   - greek small letter omega                                              -->
-<!ENTITY thetasym "&#977;">  <!-- U+03D1 NEW       - greek small letter theta symbol                                       -->
-<!ENTITY upsih    "&#978;">  <!-- U+03D2 NEW       - greek upsilon with hook symbol                                        -->
-<!ENTITY piv      "&#982;">  <!-- U+03D6 ISOgrk3   - greek pi symbol                                                       -->
-
-<!-- General Punctuation -->
-<!ENTITY bull     "&#8226;"> <!-- U+2022 ISOpub    - bullet = black small circle                                           -->
-<!ENTITY hellip   "&#8230;"> <!-- U+2026 ISOpub    - horizontal ellipsis = three dot leader                                -->
-<!ENTITY prime    "&#8242;"> <!-- U+2032 ISOtech   - prime = minutes = feet                                                -->
-<!ENTITY Prime    "&#8243;"> <!-- U+2033 ISOtech   - double prime = seconds = inches                                       -->
-<!ENTITY oline    "&#8254;"> <!-- U+203E NEW       - overline = spacing overscore                                          -->
-<!ENTITY frasl    "&#8260;"> <!-- U+2044 NEW       - fraction slash                                                        -->
-
-<!-- Letterlike Symbols -->
-<!ENTITY weierp   "&#8472;"> <!-- U+2118 ISOamso   - script capital P = power set = Weierstrass p                          -->
-<!ENTITY image    "&#8465;"> <!-- U+2111 ISOamso   - blackletter capital I = imaginary part                                -->
-<!ENTITY real     "&#8476;"> <!-- U+211C ISOamso   - blackletter capital R = real part symbol                              -->
-<!ENTITY trade    "&#8482;"> <!-- U+2122 ISOnum    - trade mark sign                                                       -->
-<!ENTITY alefsym  "&#8501;"> <!-- U+2135 NEW       - alef symbol = first transfinite cardinal                              -->
-
-<!-- Arrows -->
-<!ENTITY larr     "&#8592;"> <!-- U+2190 ISOnum    - leftwards arrow                                                       -->
-<!ENTITY uarr     "&#8593;"> <!-- U+2191 ISOnum    - upwards arrow                                                         -->
-<!ENTITY rarr     "&#8594;"> <!-- U+2192 ISOnum    - rightwards arrow                                                      -->
-<!ENTITY darr     "&#8595;"> <!-- U+2193 ISOnum    - downwards arrow                                                       -->
-<!ENTITY harr     "&#8596;"> <!-- U+2194 ISOamsa   - left right arrow                                                      -->
-<!ENTITY crarr    "&#8629;"> <!-- U+21B5 NEW       - downwards arrow with corner leftwards = carriage return               -->
-<!ENTITY lArr     "&#8656;"> <!-- U+21D0 ISOtech   - leftwards double arrow                                                -->
-<!ENTITY uArr     "&#8657;"> <!-- U+21D1 ISOamsa   - upwards double arrow                                                  -->
-<!ENTITY rArr     "&#8658;"> <!-- U+21D2 ISOtech   - rightwards double arrow                                               -->
-<!ENTITY dArr     "&#8659;"> <!-- U+21D3 ISOamsa   - downwards double arrow                                                -->
-<!ENTITY hArr     "&#8660;"> <!-- U+21D4 ISOamsa   - left right double arrow                                               -->
-
-<!-- Mathematical Operators -->
-<!ENTITY forall   "&#8704;"> <!-- U+2200 ISOtech   - for all                                                               -->
-<!ENTITY part     "&#8706;"> <!-- U+2202 ISOtech   - partial differential                                                  -->
-<!ENTITY exist    "&#8707;"> <!-- U+2203 ISOtech   - there exists                                                          -->
-<!ENTITY empty    "&#8709;"> <!-- U+2205 ISOamso   - empty set = null set = diameter                                       -->
-<!ENTITY nabla    "&#8711;"> <!-- U+2207 ISOtech   - nabla = backward difference                                           -->
-<!ENTITY isin     "&#8712;"> <!-- U+2208 ISOtech   - element of                                                            -->
-<!ENTITY notin    "&#8713;"> <!-- U+2209 ISOtech   - not an element of                                                     -->
-<!ENTITY ni       "&#8715;"> <!-- U+220B ISOtech   - contains as member                                                    -->
-<!ENTITY prod     "&#8719;"> <!-- U+220F ISOamsb   - n-ary product = product sign                                          -->
-<!ENTITY sum      "&#8721;"> <!-- U+2211 ISOamsb   - n-ary sumation                                                        -->
-<!ENTITY minus    "&#8722;"> <!-- U+2212 ISOtech   - minus sign                                                            -->
-<!ENTITY lowast   "&#8727;"> <!-- U+2217 ISOtech   - asterisk operator                                                     -->
-<!ENTITY radic    "&#8730;"> <!-- U+221A ISOtech   - square root = radical sign                                            -->
-<!ENTITY prop     "&#8733;"> <!-- U+221D ISOtech   - proportional to                                                       -->
-<!ENTITY infin    "&#8734;"> <!-- U+221E ISOtech   - infinity                                                              -->
-<!ENTITY ang      "&#8736;"> <!-- U+2220 ISOamso   - angle                                                                 -->
-<!ENTITY and      "&#8743;"> <!-- U+2227 ISOtech   - logical and = wedge                                                   -->
-<!ENTITY or       "&#8744;"> <!-- U+2228 ISOtech   - logical or = vee                                                      -->
-<!ENTITY cap      "&#8745;"> <!-- U+2229 ISOtech   - intersection = cap                                                    -->
-<!ENTITY cup      "&#8746;"> <!-- U+222A ISOtech   - union = cup                                                           -->
-<!ENTITY int      "&#8747;"> <!-- U+222B ISOtech   - integral                                                              -->
-<!ENTITY there4   "&#8756;"> <!-- U+2234 ISOtech   - therefore                                                             -->
-<!ENTITY sim      "&#8764;"> <!-- U+223C ISOtech   - tilde operator = varies with = similar to                             -->
-<!ENTITY cong     "&#8773;"> <!-- U+2245 ISOtech   - approximately equal to                                                -->
-<!ENTITY asymp    "&#8776;"> <!-- U+2248 ISOamsr   - almost equal to = asymptotic to                                       -->
-<!ENTITY ne       "&#8800;"> <!-- U+2260 ISOtech   - not equal to                                                          -->
-<!ENTITY equiv    "&#8801;"> <!-- U+2261 ISOtech   - identical to                                                          -->
-<!ENTITY le       "&#8804;"> <!-- U+2264 ISOtech   - less-than or equal to                                                 -->
-<!ENTITY ge       "&#8805;"> <!-- U+2265 ISOtech   - greater-than or equal to                                              -->
-<!ENTITY sub      "&#8834;"> <!-- U+2282 ISOtech   - subset of                                                             -->
-<!ENTITY sup      "&#8835;"> <!-- U+2283 ISOtech   - superset of                                                           -->
-<!ENTITY nsub     "&#8836;"> <!-- U+2284 ISOamsn   - not a subset of                                                       -->
-<!ENTITY sube     "&#8838;"> <!-- U+2286 ISOtech   - subset of or equal to                                                 -->
-<!ENTITY supe     "&#8839;"> <!-- U+2287 ISOtech   - superset of or equal to                                               -->
-<!ENTITY oplus    "&#8853;"> <!-- U+2295 ISOamsb   - circled plus = direct sum                                             -->
-<!ENTITY otimes   "&#8855;"> <!-- U+2297 ISOamsb   - circled times = vector product                                        -->
-<!ENTITY perp     "&#8869;"> <!-- U+22A5 ISOtech   - up tack = orthogonal to = perpendicular                               -->
-<!ENTITY sdot     "&#8901;"> <!-- U+22C5 ISOamsb   - dot operator                                                          -->
-
-<!-- Miscellaneous Technical -->
-<!ENTITY lceil    "&#8968;"> <!-- U+2308 ISOamsc   - left ceiling = apl upstile                                            -->
-<!ENTITY rceil    "&#8969;"> <!-- U+2309 ISOamsc   - right ceiling                                                         -->
-<!ENTITY lfloor   "&#8970;"> <!-- U+230A ISOamsc   - left floor = apl downstile                                            -->
-<!ENTITY rfloor   "&#8971;"> <!-- U+230B ISOamsc   - right floor                                                           -->
-<!ENTITY lang     "&#9001;"> <!-- U+2329 ISOtech   - left-pointing angle bracket = bra                                     -->
-<!ENTITY rang     "&#9002;"> <!-- U+232A ISOtech   - right-pointing angle bracket = ket                                    -->
-
-<!-- Geometric Shapes -->
-<!ENTITY loz      "&#9674;"> <!-- U+25CA ISOpub    - lozenge                                                               -->
-
-<!-- Miscellaneous Symbols -->
-<!ENTITY spades   "&#9824;"> <!-- U+2660 ISOpub    - black spade suit                                                      -->
-<!ENTITY clubs    "&#9827;"> <!-- U+2663 ISOpub    - black club suit = shamrock                                            -->
-<!ENTITY hearts   "&#9829;"> <!-- U+2665 ISOpub    - black heart suit = valentine                                          -->
-<!ENTITY diams    "&#9830;"> <!-- U+2666 ISOpub    - black diamond suit                                                    -->
-
-<!-- CVS $Revision$ $Date$ -->
-
-<!-- Portions (C) International Organization for Standardization 1986
-     Permission to copy in any form is granted for use with
-     conforming SGML systems and applications as defined in
-     ISO 8879, provided this notice is included in all copies. -->
diff --git a/docs/dtd/document.dtd b/docs/dtd/document.dtd
deleted file mode 100644
index cebe5a6..0000000
--- a/docs/dtd/document.dtd
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml encoding='US-ASCII'?>
-
-<!-- STYLEBOOK DOCUMENT DTD -->
-
-<!-- import the external blocks.ent dtd -->
-<!ENTITY % blocksEntity SYSTEM "blocks.ent">
-%blocksEntity;
-
-<!ELEMENT s1 (s2|%blocks;)*>
-<!ELEMENT s2 (s3|%blocks;)*>
-<!ELEMENT s3 (s4|%blocks;)*>
-<!ELEMENT s4 (%blocks;)*>
-
-<!ATTLIST s1 title CDATA #REQUIRED>
-<!ATTLIST s2 title CDATA #REQUIRED>
-<!ATTLIST s3 title CDATA #REQUIRED>
-<!ATTLIST s4 title CDATA #REQUIRED>
-
-<!-- CVS $Revision$ $Date$ -->
\ No newline at end of file
diff --git a/docs/dtd/entities.ent b/docs/dtd/entities.ent
deleted file mode 100644
index 039d0a4..0000000
--- a/docs/dtd/entities.ent
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml encoding="US-ASCII"?>
-
-<!ENTITY javaparsernamelong "Xerces Java Parser">
-<!ENTITY javaparsername "Xerces-J">
-<!ENTITY javaparserversion "1.2.0">
-<!ENTITY javaparserdirectory "xerces-1_2_0">
-<!ENTITY javaparserdistname "Xerces-J-bin"> <!-- name of binaries -->
diff --git a/docs/dtd/faqs.dtd b/docs/dtd/faqs.dtd
deleted file mode 100644
index df4d4b3..0000000
--- a/docs/dtd/faqs.dtd
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml encoding='US-ASCII'?>
-
-<!-- STYLEBOOK FAQS DTD -->
-
-<!-- import the external blocks.ent dtd -->
-<!ENTITY % blocksEntity SYSTEM "blocks.ent">
-%blocksEntity;
-
-<!ELEMENT faqs (faq)+>
-<!ATTLIST faqs title CDATA #REQUIRED>
-
-<!ELEMENT faq (q,a)>
-<!ATTLIST faq title CDATA #IMPLIED>
-
-
-<!ELEMENT q (#PCDATA)>
-<!ELEMENT a (%blocks;)+>
-
-<!-- CVS $Revision$ $Date$ -->
\ No newline at end of file
diff --git a/docs/dtd/links.ent b/docs/dtd/links.ent
deleted file mode 100644
index b6ccc07..0000000
--- a/docs/dtd/links.ent
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml encoding='US-ASCII'?>
-
-<!-- LINKS ENTITY -->
-<!ENTITY % links "link|anchor|jump|img|resource-ref|human-resource-ref">
-
-<!ELEMENT anchor EMPTY>
-<!ATTLIST anchor name NMTOKEN #REQUIRED>
-
-<!ELEMENT img EMPTY>
-<!ATTLIST img src CDATA #REQUIRED
-              alt CDATA #REQUIRED>
-
-<!ELEMENT link (#PCDATA|img)*>
-<!ATTLIST link idref NMTOKEN #IMPLIED
-               anchor CDATA  #IMPLIED>
-
-<!ELEMENT jump (#PCDATA|img)*>
-<!ATTLIST jump href CDATA #REQUIRED>
-
-<!-- cross-reference resource elements -->
-<!ELEMENT resource-ref 		EMPTY>
-<!ATTLIST resource-ref 		idref CDATA #REQUIRED>
-<!ELEMENT human-resource-ref 	EMPTY>
-<!ATTLIST human-resource-ref 	 idref CDATA #REQUIRED>
\ No newline at end of file
diff --git a/docs/dtd/markup.ent b/docs/dtd/markup.ent
deleted file mode 100644
index a82e0e7..0000000
--- a/docs/dtd/markup.ent
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml encoding='US-ASCII'?>
-
-<!-- MARKUP ENTITY -->
-<!ENTITY % markup "em|ref|code|br">
-
-<!-- import the external source-specific dtd -->
-<!ENTITY % externalEntity SYSTEM "entities.ent">
-%externalEntity;
-<!-- import the external charecters.ent dtd -->
-<!ENTITY % charEntity SYSTEM "characters.ent">
-%charEntity;
-<!-- import the external links.ent dtd -->
-<!ENTITY % linksEntity SYSTEM "links.ent">
-%linksEntity;
-
-<!ELEMENT em (#PCDATA|%links;)*>
-<!ELEMENT ref (#PCDATA|%links;)*>
-<!ELEMENT code (#PCDATA|%links;)*>
-<!ELEMENT br EMPTY>
-
-<!-- CVS $Revision$ $Date$ -->
diff --git a/docs/faq-build.xml b/docs/faq-build.xml
deleted file mode 100644
index 8181a72..0000000
--- a/docs/faq-build.xml
+++ /dev/null
@@ -1,212 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE faqs SYSTEM "./dtd/faqs.dtd">
-
-<faqs title="Building and Running FAQs">
-	<faq title="Swing version?">
-		<q>Which version of Swing is required?</q>
-		<a> <p>This release uses Swing 1.1 (JFC 1.1). 
-			Swing is only used by the sample programs and is not 
-			required by the parser itself.</p>
-		</a>
-	</faq>
-	<faq title="Recompling source files?">
-		<q>How do I recompile the source files?</q>
-		<a> <p>To build &javaparsername; on Windows, you need a copy of Cygnus's Cygwin.
-See <jump href="http://sourceware.cygnus.com/cygwin">http://sourceware.cygnus.com/cygwin</jump>.
-Once Cygwin is installed, you need to set two environment variables.  Edit the batch file
-BuildAll.bat to set these variables.  Execute BuildAll.bat, and then
-set your classpath to point to the src and samples directories in the
-&javaparsername; distribution.  You can then go to the top of the
-&javaparsername; tree and type 'make'.  
-</p>
-<p>
-To build &javaparsername; Java on UNIX, you need to set an environment
-variable. Edit the shell script BuildAll to set this variables.  
-Execute BuildAll, and then set your classpath to point to the src 
-and samples directories in the &javaparsername; distribution.  You can then
-go to the top of the &javaparsername; tree and type 'make'. 
-			</p>
-		</a>
-	</faq>
-	<faq title="Regenerating API documention?">
-		<q>How do I regenerate the api documentation?</q>
-		<a> <p>To regenerate the api documentation, you need to set up
-your environment to build &javaparsername;.  Instead of typing 'make', you
-type 'make apidocs'.
-			</p>
-		</a>
-	</faq>
-<!-- TBD
-	<faq title="Packaging?">
-		<q>How do I package the parser?</q>
-		<a> <p>blah
-			</p>
-		</a>
-	</faq>
--->
-	<faq title="How do I use Visual Age?">
-		<q>How do I import &javaparsername; into Visual Age for Java</q>
-		<a> 		
-		<ul>
-          <li>Why does VisualAge for Java 2.0 report problems when I import the &javaparsername; parser?
-			<br/>The current version of the &javaparsername; parser uses Swing 1.1, 
-		  	while VisualAge for Java 2.0 comes with Swing 1.0.2. The free update for the 
-            Professional version of VisualAge for Java 2.0 installs Swing 1.0.3. 
-			The most important difference between Swing 1.0.2 - 1.0.3 and 1.1 is 
-			the Java package was changed from com.sun.java.swing.* to javax.swing.*.
-			<br/>To fix the errors, you must download the Java Foundation Classes 1.1 
-			with Swing 1.1 from Sun's Java home page and import the &quot;swingall.jar&quot; 
-			file into VisualAge for Java 2.0. The Swing 1.1 package can be found at 
-            the following URL:
-			<br/><jump href="http://java.sun.com/products/jfc/index.html">http://java.sun.com/products/jfc/index.html</jump>
-			<br/>Refer to the VisualAge for Java 2.0 documentation for information about 
-			how to import a JAR file into the repository and add that code to your workspace.
-          </li>
-          <li>Are there any other tips for importing the &javaparsername; parser into VisualAge 
-		  	for Java 2.0?
-			<br/>The most useful tip applies to <em>any</em> updated code that you import 
-			into the VisualAge for Java 2.0 product. Before updating code, do the following:
-            <br/>1. version the old code
-			<br/>2. delete it from your workspace
-			<br/>3. import the new code
-            <br/>Deleting code from your workspace does not actually delete the code 
-				permanently -- the versioned code is moved to the repository where it can be 
-				retrieved later. Be aware, though, that removing code from your 
-           		workspace will cause problems with all of the other classes that use that code. 
-				VisualAge for Java 2.0 will flag them as errors but this situation is temporary. 
-				When you import the new code, the errors found when deleting the old code will be fixed.
-				<br/>If you are unsure as to how to perform any of these steps, refer to the VisualAge 
-				for Java 2.0 documentation.
-			</li>
-          </ul>
-		</a>
-	</faq>
-	<faq title="100% Pure Java compliant?">
-		<q>Is this &javaparsername; version 100% pure Java compliant?</q>
-		<a> <p>Running JavaPureCheck on the Xerces-J parser code indicated 339 
-		pure Java classes, 9 warnings, and 0 errors. The nine warnings are 
-		enumerated below with explanations. To see the entire report, click 
-		<link idref="jpc">here</link>. </p>		
-
-		<p>There are many common cases where JavaPureCheck issues warnings 
-		even though the code is pure Java. These are the most common reasons:</p>
-		<ol>
-			<li>Warning: method reference: 
-				<code>java.lang.Class.forName(java.lang.String)</code>
-				<br/>This warning is issued in the following two cases:</li>
-					<ol>
-						<li>Program code calls the <code>Class.forName(String)</code> method to 
-						dynamically load a class file. In this situation, the 
-						specified class may contain impure Java code. In the 
-						cases where this method is called directly in the parser 
-						code, an explanation is provided detailing why this 
-						warning can be ignored.</li>
-						<li>Program code makes direct reference to an object&apos;s 
-						class. For example: <code>Class stringClass = String.class;</code>. 
-						In this situation the Java compiler converts 
-						<code>String.class</code> to the method call 
-						<code>Class.forName(&quot;java.lang.String&quot;)</code>. 
-						As long as the object whose class is being referenced is 
-						pure Java, the code making the reference remains pure.</li>
-					</ol>
-			<li>Warning: possible hard-coded path: ...
-				<br/>When a String literal contains a common path separator 
-				character (e.g. &apos;/&apos; or &apos;\&apos;), JavaPureCheck assumes that 
-				it is a hard-coded path and that the class may not 
-				contain portable code. While a human tester can verify 
-				that the string is not a path, JavaPureCheck must be 
-				conservative and issue a warning.</li>
-		</ol>
-		<p>Explanations:</p>
-		<ul>
-			<li>Class: org.xml.sax.helpers.ParserFactory</li>
-				<ul><li>Warning: method reference: java.lang.Class.forName(java.lang.String)</li></ul>
-				<ul><li>Explanation: The ParserFactory class is part of the standard SAX 1.0 distribution. The warning given that this class "may load impure class" is correct -- the ParserFactory class may load impure Java class files. However, the purpose of this utility class is to load parser classes by name and therefore cannot dynamically check the pureness of parser classes loaded in this fashion. Since the Xerces-J parser does not use this method directly, it is not a problem that concerns the Xerces-J parser. </li></ul>
-			<li>Class: org.apache.xml.serialize.SerializerFactory</li>
-				<ul><li>Warning: method reference: java.lang.Class.forName(java.lang.String)</li></ul>
-				<ul><li>Explanation: The SerializerFactory supports querying a system property to dynamically instantiate a serializer by class name. However, all of the serializer classes provided in this distribution are pure. The only way to load an impure serializer is if the user provided an impure serializer implementation.</li></ul>
-			<li>Class: org.apache.xml.serialize.OutputFormat</li>
-				<ul><li>Warning: possible hard-coded path: text/xml</li></ul>
-				<ul><li>Warning: possible hard-coded path: text/plain</li></ul>
-				<ul><li>Warning: possible hard-coded path: application/pdf</li></ul>
-				<ul><li>Warning: possible hard-coded path: text/html</li></ul>
-				<ul><li>Warning: possible hard-coded path: -//W3C//DTD XHTML 1.0 Strict//EN</li></ul>
-				<ul><li>Explanation: These strings are not filenames.</li></ul>
-			<li>Class: org.apache.xml.serialize.HTMLdtd</li>
-				<ul><li>Warning: method reference: java.lang.Class.forName(java.lang.String)</li></ul>
-				<ul><li>Explanation: Referencing class object that is pure Java.</li></ul>
-			<li>Class: org.apache.html.dom.HTMLDocumentImpl</li>
-				<ul><li>Warning: method reference: java.lang.Class.forName(java.lang.String)</li></ul>
-				<ul><li>Explanation: Referencing class object that is pure Java.</li></ul>
-			<li>Class: org.apache.xerces.readers.StringReader</li>
-				<ul><li>Warning: method reference: java.lang.Class.forName(java.lang.String)</li></ul>
-				<ul><li>Explanation: Referencing class object that is pure Java.</li></ul>
-			<li>Class: org.apache.xerces.parsers.DOMParser</li>
-				<ul><li>Warning: method reference: java.lang.Class.forName(java.lang.String)</li></ul>
-				<ul><li>Explanation: The DOMParser class allows the user to set the DOM implemenation to use, by name. However, the default DOM implementation is pure Java.</li></ul>
-				<ul><li>Explanation: Referencing class object that is pure Java.</li></ul>
-			<li>Class: org.apache.xerces.utils.CharDataChunk</li>
-				<ul><li>Warning: method reference: java.lang.Class.forName(java.lang.String)</li></ul>
-				<ul><li>Explanation: Referencing class object that is pure Java.</li></ul>
-			<li>Class: org.apache.xerces.utils.UTF8DataChunk</li>
-				<ul><li>Warning: method reference: java.lang.Class.forName(java.lang.String)</li></ul>
-				<ul><li>Explanation: Referencing class object that is pure Java.</li></ul>
-		</ul>
-			<p>The results file of the JavaPureCheck can be viewed by clicking <link idref="jpc">here</link>.</p>
-			<note>The samples were not checked with JavaPureCheck and are not 
-			guaranteed to be pure Java. We reserve the right to write samples 
-			in the future that are platform specific and therefore may not 
-			pass as pure Java. The parser, however, will remain pure Java.</note>
-		</a>
-	</faq>
-	<faq title="Running on the Mac?">
-		<q>How do I get &javaparsername; to run on the Mac under MRJ?</q>
-		<a> <p><em>Prerequisites</em> (available from 
-			<jump href="http://developer.apple.com/java/">http://developer.apple.com/java/</jump>):</p>
-	        <ul>
-	          <li>MRJ 2.1 (this is the most recent version of the JVM)</li>
-	          <li>MRJ SDK 2.1 (this is the most recent version of the Java developer tools)</li>
-	        </ul>
-	        <p><em>Instructions </em>(other variations would work also):</p>
-	        <ol>
-	          <li>Download the .tar.gz file containing &javaparsername;.</li>
-	          <li>Use Stuffit Expander(tm), Suntar, or some other Macintosh tool that
-			  	<br/>supports the .tar.gz format to expand the downloaded file.</li>
-	          <li>JBindery, part of MRJ SDK 2.1, is used to create a double-clickable 
-			  	Java application with the necessary configuration information built in. 
-				It is analogous to writing a .bat or .sh script. </li>
-	          <li><em>To run the dom.DOMWriter example:</em></li>
-	          <ol>
-	            <li>Double click on JBindery to start it up.</li>
-	            <li>Click on the Classpath panel.</li>
-	            <li>Click on the &quot;Add .zip File&quot; button and add both the 
-					&quot;Xerces-J.jar&quot; and &quot;Xerces-JSamples.jar&quot; files.</li>
-	            <li>Click on the Command panel.</li>
-	            <li>Enter &quot;dom.DOMWriter&quot; as the Class name. Enter 
-					&quot;data/personal.xml&quot; in the Optional parameters box.</li>
-	            <li>Click on Save Settings button, pick a name such as &quot;Run <code>dom.DOMWriter</code>&quot; 
-					for the file, and <em>be sure</em> that &quot;Save as Application&quot; 
-					is selected (this is the default) and save the file.</li>
-	            <li>Quit JBindery.</li>
-	            <li>You can now double click on the file you created in step f to run the XJParse example.</li>
-	          </ol>
-			</ol>
-		</a>
-	</faq>
-	<faq title="Visual Cafe exception error?">
-		<q>Why do I get ArrayIndexOutOfBoundsException in the Symantec Visual Cafe debugger?</q>
-		<a> <p>The Visual Cafe debugger is set to trap <code>ArrayIndexOutOfBoundsException</code> exceptions by 
-        	default. &javaparsername; uses <code>ArrayIndexOutOfBoundsException</code> internally to signal 
-			exceptional, but not erroneous conditions. In order to run &javaparsername;2 inside 
-       		Visual Cafe's debugger, you need to turn off the trapping of these 
-			exceptions.</p>
-			<p><em>To do this:</em></p>
-        	<ol>
-          		<li>Select the &quot;Options&quot; item in the "Project" menu.</li>
-          		<li>Select the &quot;Debugger&quot; tab in the dialog which appears.</li>
-          		<li>Select &quot;Exceptions&quot; from the popup menu.</li>
-          		<li>Remove the check from the checkbox for <code>java.lang.ArrayIndexOutOfBoundsException</code>.</li>
-        	</ol>
-		</a>
-	</faq>
-</faqs>
diff --git a/docs/faq-common.xml b/docs/faq-common.xml
deleted file mode 100644
index 56b749c..0000000
--- a/docs/faq-common.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE faqs SYSTEM "./dtd/faqs.dtd">
-
-<faqs title="Common Problems">
-	<faq title="Parsing HTML Generated an Error.">
-		<q>I tried to use &javaparsername; to parse an HTML file and it generated an error. What did I do wrong?</q>
-		<a><p>Unfortunately, HTML does not, in general, follow the XML grammar rules. 
-              Most HTML files do not meet the XML style quidelines. Therefore, the XML parser 
-			  generates XML well-formedness errors.</p>
-			  <p>Typical errors include:</p>
-              <ul>
-                <li>Missing end tags, e.g. &lt;P&gt; with no &lt;/P&gt; (end tags are not required in HTML)</li>
-                <li>Missing closing slash on &lt;IMG HREF="foo" <em>/</em>&gt; (not required in HTML)</li>
-                <li>Missing quotes on attribute values, e.g. &lt;IMG width="600"&gt; (not generally required in HTML)</li>
-              </ul>
-			 <p>HTML must match the XHTML standard for well-formedness before it 
-			 can be parsed by Xerces-J or any other XML parser. You can find the 
-			 <jump href="http://www.w3c.org/TR/1999/PR-xhtml1-19991210">XHTML standard</jump> 
-			 on the <jump href="http://www.w3c.org">W3C web site</jump>.</p>
-		</a>
-	</faq>
-	<faq title="UTF-8 Character Error">
-		<q>I get an &quot;invalid UTF-8 character&quot; error.</q>
-		<a><p>There are many Unicode characters that are not allowed in an XML document, 
-              according to the XML spec. Typical disallowed characters are control 
-			  characters, even if you escape them using the Character Reference form: 
-			  &amp;#xxxx; . See the XML spec, sections 
-			  <jump href="http://www.w3.org/TR/REC-xml#charsets">2.2</jump> and 
-			  <jump href="http://www.w3.org/TR/REC-xml#sec-references">4.1</jump> 
-			  for details. If the parser is generating this error, it is very likely 
-			  that there is a character in the file that you can not see.
-              You can generally use a UNIX command like &quot;od -hc&quot; to find it.</p>
-			  
-		</a>
-	</faq>
-	<faq title="Error Accessing EBCDIC XML Files">
-		<q>I get an error when I access EBCDIC XML files, what is happening?</q>
-		<a><p>If an XML document/file is not UTF-8, then you MUST specify the encoding. 
-              When transcoding a UTF8 document to EBCDIC, remember to change this:</p>
-              <ul>
-                <li>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt; 
-				<br/>to something like this:
-				<br/>&lt;?xml version=&quot;1.0&quot; encoding=&quot;ebcdic-cp-us&quot;?&gt;
-				</li>
-              </ul>
-		</a>
-	</faq>
-	<faq title="EOF Character Error">
-		<q>I get an error on the EOF character (0x1A) -- what is happening?</q>
-		<a><p>You are probably using the <em>LPEX</em> 
-		editor, which automatically inserts an End-of-file character (0x1A) at the end of your 
-		XML document (other editors might do this as well). Unfortunately, the 
-		EOF character (0x1A) is an illegal character according to the XML specification, 
-		and &javaparsername; correctly generates an error.</p>
-		</a>
-	</faq>
-	<faq title='DOS Filenames No Longer Work'>
-		<q>I used to be able to use DOS filenames with the parser and now
-		they don't work. Why not?</q>
-		<a><p>DOS filenames are not legal URIs as required by the XML 1.0
-		specification. Therefore, it was an error for the parser to accept
-		DOS filenames. This bug is now fixed.</p>
-		<p>DOS filenames can be converted to legal URIs, however. For
-		example, the DOS filename "c:\xerces\data\personal.xml" would become 
-		"file:///c:/xerces/data/personal.xml", which is a legal URI.</p>
-		</a>
-	</faq>
-</faqs>
diff --git a/docs/faq-general.xml b/docs/faq-general.xml
deleted file mode 100644
index cc64ec5..0000000
--- a/docs/faq-general.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE faqs SYSTEM "./dtd/faqs.dtd">
-
-<faqs title="General FAQs">
-
-	<faq title="New Features?">
-		<q>What are the new features?</q>
-		<a>
-			<p>Here are some of the new features in &javaparsername;:</p>
-		     <ul>
-			     <li>Additional support for W3C XML Schema Language.</li>
-			     <li>DOS filenames no longer work. See Common Problems
-				section of the FAQ.</li>
-		     </ul>
-	<anchor name="valid"/>
-		</a>
-	</faq>
-	
-	<faq title="Validation">
-		<q>How do I turn on validation?</q>
-		<a>
-			<p>You can turn validation on and off via methods available
-			on the SAX2 <code>XMLFilter</code> interface. While only the 
-			<code>SAXParser</code> implements the <code>XMLFilter</code>
-			interface, the methods required for turning on validation
-			are available to both parser classes, DOM and SAX.
-			<br/>
-            The code snippet below shows how to turn validation on -- assume that <ref>parser</ref>
-            is an instance of either
-            <code>org.apache.xerces.parsers.SAXParser</code> or
-            <code>org.apache.xerces.parsers.DOMParser</code>. <br/><br/>
-     		<code>parser.setFeature("http://xml.org/sax/features/validation", true);</code>
-			</p>
-		</a>
-	</faq>
-	
-	<faq title="International Encodings">
-		<q>What international encodings are supported by &javaparsername;?</q>
-		<a>
-			<ul>
-          		<li>UTF-8</li>
-          		<li>UTF-16 Big Endian, UTF-16 Little Endian</li>
-          		<li>IBM-1208</li>
-          		<li>ISO Latin-1 (ISO-8859-1)</li>
-          		<li>ISO Latin-2 (ISO-8859-2) [Bosnian, Croatian, Czech, 
-					Hungarian, Polish, Romanian, Serbian (in Latin transcription), 
-					Serbocroatian, Slovak, Slovenian, Upper and Lower Sorbian]</li>
-          		<li>ISO Latin-3 (ISO-8859-3) [Maltese, Esperanto]</li>
-          		<li>ISO Latin-4 (ISO-8859-4)</li>
-          		<li>ISO Latin Cyrillic (ISO-8859-5)</li>
-          		<li>ISO Latin Arabic (ISO-8859-6)</li>
-          		<li>ISO Latin Greek (ISO-8859-7)</li>
-          		<li>ISO Latin Hebrew (ISO-8859-8)</li>
-          		<li>ISO Latin-5 (ISO-8859-9) [Turkish]</li>
-          		<li>Extended Unix Code, packed for Japanese (euc-jp, eucjis)</li>
-          		<li>Japanese Shift JIS (shift-jis)</li>
-          		<li>Chinese (big5)</li>
-          		<li>Chinese for PRC (mixed 1/2 byte) (gb2312)</li>
-          		<li>Japanese ISO-2022-JP (iso-2022-jp)</li>
-          		<li>Cyrllic (koi8-r)</li>
-          		<li>Extended Unix Code, packed for Korean (euc-kr)</li>
-          		<li>Russian Unix, Cyrillic (koi8-r)</li>
-          		<li>Windows Thai (cp874)</li>
-          		<li>Latin 1 Windows (cp1252)</li>
-          		<li>cp858</li>
-          		<li>EBCDIC encodings:</li>
-          		<ul>
-            		<li>EBCDIC US (ebcdic-cp-us)</li>
-            		<li>EBCDIC Canada (ebcdic-cp-ca)</li>
-            		<li>EBCDIC Netherland (ebcdic-cp-nl)</li>
-            		<li>EBCDIC Denmark (ebcdic-cp-dk)</li>
-            		<li>EBCDIC Norway (ebcdic-cp-no)</li>
-            		<li>EBCDIC Finland (ebcdic-cp-fi)</li>
-            		<li>EBCDIC Sweden (ebcdic-cp-se)</li>
-            		<li>EBCDIC Italy (ebcdic-cp-it)</li>
-            		<li>EBCDIC Spain, Latin America (ebcdic-cp-es)</li>
-            		<li>EBCDIC Great Britain (ebcdic-cp-gb)</li>
-            		<li>EBCDIC France (ebcdic-cp-fr)</li>
-            		<li>EBCDIC Hebrew (ebcdic-cp-he)</li>
-            		<li>EBCDIC Switzerland (ebcdic-cp-ch)</li>
-            		<li>EBCDIC Roece (ebcdic-cp-roece)</li>
-            		<li>EBCDIC Yugoslavia (ebcdic-cp-yu)</li>
-            		<li>EBCDIC Iceland (ebcdic-cp-is)</li>
-            		<li>EBCDIC Urdu (ebcdic-cp-ar2)</li>
-            		<li>Latin 0 EBCDIC</li>
-            		<li>EBCDIC Arabic (ebcdic-cp-ar1)</li>
-          		</ul>
-        	</ul>
-		</a>
-	</faq>
-	
-</faqs>
diff --git a/docs/faq-migrate.xml b/docs/faq-migrate.xml
deleted file mode 100644
index 7981040..0000000
--- a/docs/faq-migrate.xml
+++ /dev/null
@@ -1,227 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE faqs SYSTEM "./dtd/faqs.dtd">
-
-<faqs title="Migrating to &javaparsernamelong;">
-	<faq title="What should I be aware of when using various DOM parsers?">
-		<q>What should I be aware of when using various DOM parsers?</q>
-		<a><p>There are a couple of points to note when using the various 
-			DOM parsers. This FAQ discusses some of the differences between the 
-			Xerces, Oracle and Sun XML parsers:</p>
-			<ol>
-				<li><em>Parsing methods:</em>
-					<br/>The &javaparsername; and Oracle parsers have a parser object that parses 
-					XML files and constructs a DOM tree which is queried 
-					<ref>after</ref> parsing. 
-					<br/>The Sun parser calls a static method on the 
-					<code>XmlDocument</code> class 
-					to parse and construct a DOM tree.</li>
-				<li><em>Specifying the source file:</em>
-					<br/>All three parsers allow specifying the source of the 
-					XML document using the SAX <code>InputSource</code> object 
-					as well as parsing from <code>java.io.InputStream</code> 
-					and <code>java.io.Reader</code> object.</li>
-				<li><em>Error handling:</em>
-					<br/>The &javaparsername; parser uses the SAX <code>ErrorHandler</code> mechanism 
-					on all parser types, including DOM. 
-					<br/>The Oracle parser only allows you to specify which 
-					output stream or writer you want the error to be written. 
-					<br/>The Sun parser has no way to request 
-					error notification when parsing XML files into DOM trees. 
-					An exceptions will be thrown if an error occurs during 
-					parsing.</li>
-				<li><em>Validation:</em>
-					<br/>The &javaparsername; and Oracle DOM parsers use a method to 
-					set validation. 
-					<br/>Because of the way that DOM documents are constructed from XML files 
-					in the Sun parser, validation is set via a parameter to the static 
-					<code>createXmlDocument</code> method.</li>
-				<li><em>Standard versus proprietary features:</em>
-					<br/>If the user has written their programs using the W3C DOM API, 
-					then migrating to &javaparsername; is easy. If however, the user takes 
-					advantage of non-standard, proprietary features of the Oracle and Sun 
-					parsers and DOM implementations, migration will be harder. 
-					This document does not 
-					go into any detail regarding migration of features specific to each 
-					parser&apos;s implementation that are non-standard.</li>
-			</ol>
-			<p><em>Samples:</em></p>
-			<p>Xerces 1.0.x:</p>
-
-<source>// instantiate parser
-org.apache.xerces.parsers.DOMParser parser;
-parser = new org.apache.xerces.parsers.DOMParser();
-
-// specifying validation
-boolean validate = /* true or false */;
-parser.setFeature("http://xml.org/sax/features/validation", validate);
-
-// installing error handler
-org.xml.sax.ErrorHandler handler = /* SAX error handler */;
-parser.setErrorHandler(handler);
-
-// parsing document from URI string
-String uri = /* uri */;
-parser.parse(uri);
-
-// parsing document from input stream
-java.io.InputStream stream = /* input stream */;
-parser.parse(new org.xml.sax.InputSource(stream));
-
-// parsing document from reader
-java.io.Reader reader = /* reader */;
-parser.parse(new org.xml.sax.InputSource(reader));
-
-// querying document after parse
-org.w3c.dom.Document document;
-document = parser.getDocument();</source>
-
-<p>Oracle 2.0.2.x:</p>
-
-<source>// instantiate parser
-oracle.xml.parser.v2.DOMParser parser;
-parser = oracle.xml.parser.v2.DOMParser();
-
-// specifying validation
-boolean validate = /* true or false */;
-parser.setValidationMode(validate);
-
-// installing error stream to output stream (with and without encoding)
-java.io.OutputStream output = /* output stream */;
-String encoding = /* Java encoding name */;
-parser.setErrorStream(output);
-parser.setErrorStream(output, encoding);
-
-// installing error stream to print writer
-java.io.PrintWriter printer = /* print writer */;
-parser.setErrorStream(printer);
-
-// parsing document from URI string
-String uri = /* uri */;
-parser.parse(uri);
-
-// parsing document from input stream
-java.io.InputStream stream = /* input stream */;
-parser.parse(stream);
-
-// parsing document from reader
-java.io.Reader reader = /* reader */;
-parser.parse(reader);
-
-// querying document after parse
-org.w3c.dom.Document document;
-document = parser.getDocument();</source>
-
-<p>Sun TR2:</p>
-
-<source>// parsing document from URI string
-String uri = /* uri */;
-Document document;
-document = com.sun.xml.tree.XmlDocument.createXmlDocument(uri);
-
-// parsing document from URI string (with validation)
-boolean validate = /* true or false */;
-document = com.sun.xml.tree.XmlDocument.createXmlDocument(uri, validate);
-
-// parsing document from input stream
-java.io.InputStream stream = /* input stream */;
-document = com.sun.xml.tree.XmlDocument.createXmlDocument(stream, validate);
-
-// parsing document from reader
-java.io.Reader reader = /* reader */;
-document = com.sun.xml.tree.XmlDocument.createXmlDocument
-           (new org.xml.sax.InputSource(reader), validate);</source>
-		</a>
-	</faq>
-	
-	<faq title="What should I be aware of when using various SAX parsers?">
-		<q>What should I be aware of when using various SAX parsers?</q>
-		<a><p>There are a couple of points to note when using the various 
-		SAX parsers:</p>
-			<p>The SAX API has detailed specifications on how documents are parsed 
-			and entities are resolved, so little migration effort required. 
-			The only change is the construction of the SAX parser. 
-			See the following examples for construction details.</p>
-
-			<note>Regarding validation: 
-			<br/>If a parser is SAX2 
-			compliant, there is a standard way of turning on validation. The 
-			Xerces parser implements the appropriate methods today, even 
-			though they haven't been finalized, yet. The parsers downloaded 
-			from Oracle and Sun do not yet implement these methods. 
-			The Oracle parser has a method to turn validation on and 
-			off. The Sun parser requires you to instantiate a 
-			separate parser object to perform validation.</note>
-			
-			<p><em>Samples:</em></p>
-			<p>Xerces 1.0.x:</p>
-<source>// instantiate parser
-org.apache.xerces.parsers.SAXParser parser;
-parser = new org.apache.xerces.parsers.SAXParser();
-
-// specifying validation
-boolean validate = /* true or false */;
-parser.setFeature("http://xml.org/sax/features/validation", validate);
-
-// installing error handler
-org.xml.sax.ErrorHandler errorHandler = /* SAX error handler */;
-parser.setErrorHandler(errorHandler);
-
-// installing document handler
-org.xml.sax.DocumentHandler documentHandler = /* SAX document handler */;
-parser.setDocumentHandler(documentHandler);
-
-// parsing document from URI string
-String uri = /* uri */;
-parser.parse(uri);
-
-// parsing document from input stream
-java.io.InputStream stream = /* input stream */;
-parser.parse(new org.xml.sax.InputSource(stream));
-
-// parsing document from reader
-java.io.Reader reader = /* reader */;
-parser.parse(new org.xml.sax.InputSource(reader));</source>
-			<p>Oracle 2.0.2.x:</p>
-<source>// instantiate parser
-oracle.xml.parser.v2.SAXParser parser;
-parser = oracle.xml.parser.v2.SAXParser();
-
-// specifying validation
-boolean validate = /* true or false */;
-parser.setValidationMode(validate);
-
-// ... the rest is the same as Xerces ...</source>
-			<p>Sun TR2:</p>
-<source>// instantiate parser
-boolean validate = /* true or false */;
-com.sun.xml.parser.Parser parser;
-if (validate) {
-    parser = new com.sun.xml.parser.ValidatingParser();
-}
-else {
-    parser = new com.sun.xml.parser.Parser();
-}
-
-// ... the rest is the same as Xerces ...</source>
-
-		</a>
-	</faq>
-	
-	<faq title="Migrating from XML4J Version 2.0.x">
-		<q>How do I migrate my code from XML4J Version 2.0.x?</q>
-		<a>
-	     <p>Migrating from the version 2.0.x native SAX and DOM parser
-	      classes should be straight forward.</p>
-		<table>
-			<tr><th>change this XML4J class</th><th>to this &javaparsername; class</th></tr>
-			<tr><td>com.ibm.xml.parsers.SAXParser</td> <td>org.apache.xerces.parsers.SAXParser</td></tr>
-			<tr><td>com.ibm.xml.parsers.ValidatingSAXParser</td>  <td>org.apache.xerces.parsers.SAXParser + switch</td></tr>
-			<tr><td>com.ibm.xml.parsers.NonValidatingDOMParser</td>  <td>org.apache.xerces.parsers.DOMParser</td></tr>
-			<tr><td>com.ibm.xml.parsers.DOMParser</td>  <td>org.apache.xerces.parsers.DOMParser + switch</td></tr>
-		</table>
-		<p>Table entries that say " + switch" mean that you should use the
-		Configurable API to turn validation on.  See the answer in <link idref="faq-general" anchor="valid">Validation</link>.</p>
-		</a>
-	</faq>
-	
-</faqs>
diff --git a/docs/faq-performance.xml b/docs/faq-performance.xml
deleted file mode 100644
index 230fc46..0000000
--- a/docs/faq-performance.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE faqs SYSTEM "./dtd/faqs.dtd">
-
-<faqs title="Performance FAQs">
-
-	<faq title="General Performance">
-		<q>General Performance</q>
-		<a><p>Don't use XML where it doesn't make sense. XML is not a panacea. 
-		You will not get good performance by transferring and parsing a 
-		lot of XML files. </p>
-		<p>Using XML is memory, CPU, and network intensive.</p></a>
-	</faq>
-	
-	<faq title="Parser Performance">
-		<q>Parser Performance</q>
-		<a><p>Avoid creating a new parser each time you parse; reuse parser 
-		instances. A pool of reusable parser instances might be a good idea 
-		if you have multiple threads parsing at the same time.</p>
-		</a>
-	</faq>
-	<faq title="Parsing Documents Performance">
-		<q>Parsing Documents Performance</q>
-		<a><ul>
-			<li>Convert the document to US ASCII ("US-ASCII") or Unicode 
-			("UTF-8" or "UTF-16") before parsing. Documents written using 
-			ASCII are the fastest to parse because each character is 
-			guaranteed to be a single byte and map directly to their 
-			equivalent Unicode value. For documents that contain Unicode 
-			characters beyond the ASCII range, multiple byte sequences 
-			must be read and converted for each character. There is a 
-			performance penalty for this conversion. The UTF-16 encoding 
-			alleviates some of this penalty because each character is 
-			specified using two bytes, assuming no surrogate characters. 
-			However, using UTF-16 can roughly double the size of the 
-			original document which takes longer to parse.</li>
-			<li>Explicitly specify "US-ASCII" encoding if your document is in 
-			ASCII format. If no encoding is specified, the XML specification 
-			requires the parser to assume UTF-8 which is slower to process.</li>
-			<li>Avoid external entities and external DTDs. The extra file 
-			opens and transcoding setup is expensive.</li>
-			<li>Reduce character count; smaller documents are parsed quicker. 
-			Replace elements with attributes where it makes sense. Avoid 
-			gratuitous use of whitespace because the parser must scan past it.</li>
-			<li>Avoid using too many default attributes. Defaulting 
-			attribute values slows down processing.</li>
-		</ul>
-		</a>
-	</faq>
-	<faq title="XML Application Performance">
-		<q>XML Application Performance</q>
-		<a><ul>
-			<li>Turn validation off if you don't need it. Validation is 
-			expensive. Also, avoid using a DOCTYPE line in your XML document. 
-			The current version of the parser will always read the DTD if the 
-			DOCTYPE line is specified even when not validating.</li>
-			<li>For large documents, avoid using DOM which uses a lot of 
-			memory. Instead, use SAX if appropriate. The DOM parser requires 
-			that the entire document be read into memory before the 
-			application processes the document. The SAX parser uses very 
-			little memory and notifies the application as parts of the 
-			document are parsed.</li>
-		</ul>
-		</a>
-	</faq>
-</faqs>
diff --git a/docs/faq-write.xml b/docs/faq-write.xml
deleted file mode 100644
index bc24b5e..0000000
--- a/docs/faq-write.xml
+++ /dev/null
@@ -1,285 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE faqs SYSTEM "./dtd/faqs.dtd">
-
-<faqs title="Writing Application FAQs">
-	<faq title="Creating a DOM Parser">
-		<q>How do I create a DOM parser?</q>
-        <a>
-<source>import org.apache.xerces.parsers.DOMParser;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-import java.io.IOException;
-
-  ...
-
-String xmlFile = &quot;file:///&javaparserdirectory;/data/personal.xml&quot;; 
-
-DOMParser parser = new DOMParser();
-
-try {
-    parser.parse(xmlFile);
-
-} catch (SAXException se) {
-    se.printStackTrace();
-} catch (IOException ioe) {
-    ioe.printStackTrace();
-}
-
-Document document = parser.getDocument();</source>
-		</a>
-	</faq>
-	
-	<faq title="Creating a SAX Parser">
-		<q>How do I create a SAX parser?</q>
-		<a>
-<source>import org.apache.xerces.parsers.SAXParser;
-import org.xml.sax.Parser;
-import org.xml.sax.ParserFactory;
-import org.xml.sax.SAXException;
-import java.io.IOException; 
-
-  ...
-
-String xmlFile = &quot;file:///&javaparserdirectory;/data/personal.xml&quot;; 
-
-String parserClass = &quot;org.apache.xerces.parsers.SAXParser&quot;;
-Parser parser = ParserFactory.makeParser(parserClass);
-
-try {
-    parser.parse(xmlFile);
-} catch (SAXException se) {
-    se.printStackTrace();
-} catch (IOException ioe) {
-	ioe.printStackTrace();
-}</source>
-		</a>
-	</faq>
-	
-	<faq title="Controlling parser options">
-		<q>How do I control the various parser options?</q>
-		<a><p>For this release, all of the parser control API's have
-		been switched over to the SAX2 Configurable interface.  This
-		provide a uniform and extensible mechanism for setting and
-		querying parser options.  Here are guides to the set of
-		available <link idref="features">features</link> and
-		<link idref="properties">properties</link>.</p>
-		</a>
-	</faq>
-	<faq title="Using lazy DOM">
-		<q>How do I use the lazy evaluating DOM implementation?</q>
-		<a><p>The DOM parser class <code>org.apache.xerces.parsers.DOMParser</code> uses a 
-		DOM implementation that can take advantage of lazy evaluation to 
-		improve performance. There is also a mode where the parser creates 
-		all of the nodes as the document is parsed. By default, the parser 
-		uses the lazy evaluation DOM implementation.</p>
-		<p>Nodes in the DOM tree are only created when they are accessed. 
-		The initial call to <code>getDocument()</code> will return a DOM tree that 
-		consists only of the Document node. All of the immediate children 
-		of a Node are created when any of that Node's children are accessed. 
-		This shortens the time it takes to parse an XML file and create a DOM 
-		tree at the expense of requiring more memory during parsing and 
-		traversing the document.</p>
-		<p>The lazy evaluation feature is set using the SAX2 Configurable 
-		interface. To turn off this feature, use the following code:</p>
-<source>DOMParser parser = new DOMParser();
-parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);</source>
-		<p>To turn the lazy evaluation feature back on, use the following code:</p>
-
-<source>parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", true);</source>
-		</a>
-	</faq>
-	
-	<faq title="Handling Errors">
-		<q>How do handle errors?</q>
-		<a><p>When you create a parser instance, the default error handler does nothing. 
-		This means that your program will fail silently when it encounters an error. 
-		You should register an error handler with the parser by supplying a class 
-		which implements the <code>org.xml.sax.ErrorHandler</code>
-		interface. This is true regardless of whether your parser is a
-		DOM based or SAX based parser.</p>
-		</a>
-	</faq>
-	
-	<faq title="Controlling Entity Representation">
-		<q>How can I control the way that entities are represented in
-		the DOM?</q>
-		<a><p>
-        The feature <code>http://apache.org/xml/features/dom/create-entity-ref-nodes</code>
-        controls how entities appear in the DOM tree. When this
-        feature is set to true (the default), an occurance of an
-        entity reference in the XML document will be represented by a
-        subtree with an EntityReference node at the root whose
-        children represent the entity expansion.</p>
-
-    	<p>If the property is false, an entity reference in the XML
-    	document is represented by only the nodes that represent the
-    	entity expansion.</p> 
-
-        <p>In either case, the entity expansion will be a DOM tree
-        representing the structure of the entity expansion, not a text
-        node containing the entity expansion as text.</p>
-		</a>
-	</faq>
-	
-	<faq title="What does &quot;non-validating&quot; mean?">
-		<q>Why does &quot;non-validating&quot; not mean &quot;well-formedness checking only&quot;?</q>
-		<a><p>Using a &quot;non-validating&quot; parser does not mean that only well-formedness 
-        checking is done! There are still many things that the XML specification 
-		requires of the parser, including entity substitution, defaulting of 
-		attribute values, and attribute normalization.</p>
-        <p>This table describes what &quot;non-validating&quot; really means for &javaparsername; parsers. 
-		In this table, "no DTD" means no internal or external DTD subset is present.</p>
-		
-        <table>
-			<tr><tn/>
-				<th colspan="2">non-validating parsers</th>
-				<th colspan="2">validating parsers</th>
-          	</tr>
-          	<tr><tn/>							<th>DTD present</th>	<th>no DTD</th>	<th>DTD present</th>	<th>no DTD</th></tr>
-          	<tr><th>DTD is read</th>			<td>Yes</td>			<td>No</td>		<td>Yes</td>			<td>Error</td></tr>
-          	<tr><th>entity substitution</th>	<td>Yes</td>			<td>No</td>		<td>Yest</td>			<td>Error</td></tr>
-          	<tr><th>defaulting of attributes</th>	<td>Yes</td>		<td>No</td>		<td>Yes</td>			<td>Error</td></tr>
-          	<tr><th>attribute normalization</th>	<td>Yes</td>		<td>No</td>		<td>Yes</td>			<td>Error</td></tr>
-          	<tr><th>checking against model</th>		<td>No</td>			<td>No</td>		<td>Yes</td>			<td>Error</td></tr>
-        </table>
-		</a>
-	</faq>
-	
-	<faq title="Associating Data with a Node">
-		<q>How do I associate my own data with a node in the DOM tree?</q>
-		<a><p>The class <code>org.apache.xerces.dom.NodeImpl</code> provides a 
-			<code>void setUserData(Object o)</code> and an <code>Object getUserData()</code>
-         	method that you can use to attach any object to a node in the DOM tree.</p>
-                <p>Beware that you should try and remove references to your
-                  data on nodes you no longer use (by calling
-                  <code>setUserData(null)</code>, or these nodes will not be
-                  garbage collected until the whole document is.</p>
-		</a>
-	</faq>
-	
-	<faq title="Parsing Several Documents">
-		<q>How do I more efficiently parse several documents sharing a common DTD?</q>
-		<a>	<p>DTDs are not currently cached by the parser. The common DTD, since it is 
-        	specified in each XML document, will be re-parsed once for each document.</p>
-			<p>However, there are things that you can do now, to make the process of 
-			reading DTD's more efficient:</p>
-        	<ul>
-          		<li>keep your DTD and DTD references local</li>
-          		<li>use internal DTD subsets, if possible</li>
-          		<li>load files from server to local client before parsing</li>
-          		<li>Cache document files into a local client cache. You should do an 
-					HTTP header request to check whether the document has changed, 
-					before accessing it over the network.</li>
-          		<li>Do not reference an external DTD or internal DTD subset at all. 
-					In this case, no DTD will be read.</li>
-				<li>Use a custom <code>EntityResolver</code> and keep common 
-				DTDs in a memory buffer.</li>
-        	</ul>
-		</a>
-	</faq>
-	
-	<faq title="How do I access the DOM Level 2 functionality?">
-		<q>How do I access the DOM Level 2 functionality?</q>
-		<a><p>The <jump href="http://www.w3.org/TR/DOM-Level-2/">DOM Level 2</jump> 
-			specification is at the stage of 
-			"Candidate Recommendation" (CR), which allows feedback from implementors 
-			before it becomes a "Recommedation". It is comprised of "core" 
-			functionality, which is mainly the DOM 
-			<jump href="http://www.w3.org/TR/REC-xml-names/">Namespaces</jump> implementation, 
-			and a number of optional modules (called Chapters in the spec).</p>
-			<p>Please refer to:</p>
-			<p><jump href="http://www.w3.org/TR/DOM-Level-2/">
-			http://www.w3.org/TR/DOM-Level-2/</jump> for the 
-			latest DOM Level 2 specification.</p>
-			<p>The following DOM Level 2 modules are fully implemented in &javaparsername;: </p>
-			<ul>
-				<li><jump href="http://www.w3.org/TR/DOM-Level-2/core.html">
-					Chapter 1: Core</jump> - most of these enhancements are for 
-					Namespaces, and can be acessed through additional functions which 
-					have been added directly to the <ref>org.w3c.dom.*</ref> classes.</li>
-
-				<li><jump href="http://www.w3.org/TR/DOM-Level-2/events.html">
-					Chapter 6: Events</jump> - The <ref>org.w3c.dom.events.EventTarget</ref> 
-					interface is implemented by all <code>Nodes</code> of the DOM. 
-					The &javaparsername; DOM implementation handles all of the event 
-					triggering, capture and flow.</li>
-
-				<li><jump href="http://www.w3.org/TR/DOM-Level-2/traversal.html">
-					Chapter 7: Traversal</jump> - The Traversal module interfaces 
-					are located in <ref>org.w3c.dom.traversal</ref>. 
-					The <code>NodeIterator</code> and <code>TreeWalker</code>, and 
-					<code>NodeFilter</code> interfaces have been supplied to allow 
-					traversal of the DOM at a higher-level. Our DOM Document 
-					implementation class, <code>DocumentImpl</code> class now 
-					implements <code>DocumentTraversal</code>, which supplies the 
-					factory methods to create the iterators and treewalkers.</li>
-
-				<li><jump href="http://www.w3.org/TR/DOM-Level-2/range.html">
-				Chapter 8. Range</jump> - The Range module interfaces are 
-					located in <ref>org.w3c.dom.range</ref>. The Range interface 
-					allows you to specify ranges or selections using boundary 
-					points in the DOM, along with functions (like delete, 
-					clone, extract..) that can be performed on these ranges. 
-					Our DOM Document implementation class, <code>DocumentImpl</code> 
-					class now implements <code>DocumentRange</code>, that supplies 
-					the factory method to create a <code>Range</code>.</li>
-			</ul>
-			<note>Since the DOM Level 2 is still in the CR phase, some changes 
-			to these specs are still possible. The purpose of this phase is to 
-			provide feedback to the W3C, so that the specs can be clarified and 
-			implementation concerns can be addressed.</note>		
-		</a>
-	</faq>
-	
-	<faq title="How do I read data from a stream as it arrives?">
-		<q>How do I read data from a stream as it arrives?</q>
-		<a><p>For performance reasons, all the standard Xerces processing
-		uses readers which buffer the input.  In order to read data
-		from a stream as it arrives, you need to instruct Xerces to
-		use the <code>StreamingCharReader</code> class as its reader.
-		To do this, create a subclass of
-		<code>org.apache.xerces.readers.DefaultReaderFactory</code>
-		and override <code>createCharReader</code> and
-		<code>createUTF8Reader</code> as shown below.
-		</p>
-<source>public class StreamingCharFactory extends org.apache.xerces.readers.DefaultReaderFactory {
-  public XMLEntityHandler.EntityReader createCharReader(XMLEntityHandler entityHandler,
-                                                        XMLErrorReporter errorReporter,
-                                                        boolean sendCharDataAsCharArray,
-                                                        Reader reader,
-                                                        StringPool stringPool) throws Exception
-    {
-      return new org.apache.xerces.readers.StreamingCharReader(entityHandler, 
-                 errorReporter, sendCharDataAsCharArray, reader, stringPool);
-    }
-
-  public XMLEntityHandler.EntityReader createUTF8Reader(XMLEntityHandler entityHandler,
-                                                        XMLErrorReporter errorReporter,
-                                                        boolean sendCharDataAsCharArray,
-                                                        InputStream data,
-                                                        StringPool stringPool) throws Exception
-    {
-      XMLEntityHandler.EntityReader reader;
-      reader = new org.apache.xerces.readers.StreamingCharReader(entityHandler,
-                   errorReporter, sendCharDataAsCharArray, 
-                   new InputStreamReader(data, "UTF8"), stringPool);
-      return reader;
-    }
-
-}</source>
-		<p>In your program, after you instantiate a parser class, replace
-	    the <code>DefaultReaderFactory</code> with <code>StreamingCharFactory</code>, and be
-	    sure to wrap the <code>InputStream</code> that you are reading
-	    from with an <code>InputStreamReader</code>.</p>
-<source>InputStream in = ... ;
-SAXParser p = new SAXParser();
-DocumentHandler h = ... ;
-// set the correct reader factory
-p.setReaderFactory(((StreamingSAXClient)h).new StreamingCharFactory());
-p.setDocumentHandler(h);
-
-// be sure to wrap the input stream in an InputStreamReader.
-p.parse(new InputSource(new InputStreamReader(in)));</source>
-		</a>
-	</faq>
-</faqs>
diff --git a/docs/features.xml b/docs/features.xml
deleted file mode 100644
index 8c53e76..0000000
--- a/docs/features.xml
+++ /dev/null
@@ -1,251 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="Features">
-	<s2 title="Setting Features">
-        <anchor name="features"/>
-		<p>To set a feature on either org.apache.xerces.parsers.SAXParser or 
-		org.apache.xerces.parsers.DOMParser, you should use the SAX2 
-		method <code>setFeature(String,boolean)</code>. To query a
-		feature, use the SAX2 method <code>getFeature(String)</code>.</p>
-		<p>For example, to turn on validation:</p>
-<source>SAXParser p=new SAXParser();
-try {
-  p.setFeature("http://xml.org/sax/features/validation", true);
-} catch (SAXException e) {
-  System.out.println("error in setting up parser feature");
-}</source>
-	</s2>
-	
-	<s2 title="General Features">
-		<anchor name="validation"/>
-		<p>http://xml.org/sax/features/validation</p>
-		<table>
-			<tr><th>True:</th>		<td>Validate the document.</td></tr>
-			<tr><th>False:</th>		<td>Do not validate the document.</td></tr>
-			<tr><th>Default:</th>	<td>false</td></tr>
-			<tr><th>Access:</th>	<td>(parsing) read-only; (not parsing) read/write</td></tr>
-			<tr><th>Note:</th>		<td>If this feature is set to true, the document must specify a grammar. 
-					   				If this feature is set to false, the document may specify a grammar 
-					  				and that grammar will be parsed but no validation of the document 
-					   				contents will be performed.</td></tr>
-			<tr><th>See:</th>		<td><link anchor="dynamic">http://apache.org/xml/features/validation/dynamic</link>
-									<br/><link anchor="namespaces">http://xml.org/sax/features/namespaces</link></td></tr>
-		</table>
-		
-		<anchor name="external-general-entities"/>
-		<p>http://xml.org/sax/features/external-general-entities</p>
-		<table>
-			<tr><th>True:</th>		<td>Include external general (text) entities.</td></tr>
-			<tr><th>False:</th>		<td>Do not include external general entities.</td></tr>
-			<tr><th>Default:</th>	<td>true</td></tr>
-			<tr><th>Access:</th>	<td>(parsing) read-only; (not parsing) read/write</td></tr>
-			<tr><th>See:</th>
-				<td><link anchor="external-parameter-entities">http://xml.org/sax/features/external-parameter-entities</link></td></tr>
-		</table>
-		
-		<anchor name="external-parameter-entities"/>
-		<p>http://xml.org/sax/features/external-parameter-entities</p>
-		<table>
-			<tr><th>True:</th>		<td>Include external parameter entities and the external DTD subset.</td></tr>
-			<tr><th>False:</th>		<td>Do not include external parameter entities or the external DTD subset.</td></tr>
-			<tr><th>Default:</th>	<td>true</td></tr>
-			<tr><th>Access:</th>	<td>(parsing) read-only; (not parsing) read/write</td></tr>
-			<tr><th>See:</th>
-				<td><link anchor="external-parameter-entities">http://xml.org/sax/features/external-parameter-entities</link></td></tr>
-		</table>
-		
-		<anchor name="namespaces"/>
-		<p>http://xml.org/sax/features/namespaces</p>
-		<table>
-			<tr><th>True:</th>		<td>Perform namespace processing: prefixes will be stripped off element and 
-					  				 attribute names and replaced with the corresponding namespace URIs. By 
-					  				 default, the two will simply be concatenated, but the namespace-sep core 
-					  				 property allows the application to specify a delimiter string for 
-					  				 separating the URI part and the local part.</td></tr>
-			<tr><th>False:</th>		<td>Do not perform namespace processing.</td></tr>
-			<tr><th>Default:</th>	<td>false</td></tr>
-			<tr><th>Access:</th>	<td>(parsing) read-only; (not parsing) read/write</td></tr>
-			<tr><th>Note:</th>		<td>If the validation feature is set to true, then the document must contain 
-   									a grammar that supports the use of namespaces.</td></tr>
-			<tr><th>See:</th>		<td><link anchor="validation">http://xml.org/sax/features/validation</link>
-									<br/><link idref="properties" anchor="namespace-sep">http://xml.org/sax/properties/namespace-sep</link></td></tr>
-		</table>
-		
-		<anchor name="schema"/>
-		<p>http://apache.org/xml/features/validation/schema</p>
-		<table>
-			<tr><th>True:</th>		<td>Turn on XML Schema support.</td></tr>
-			<tr><th>False:</th>		<td>Turn off XML Schema support.</td></tr>
-			<tr><th>Default:</th>	<td>true</td></tr>
-		</table>
-
-		<anchor name="dynamic"/>
-		<p>http://apache.org/xml/features/validation/dynamic</p>
-		<table>
-			<tr><th>True:</th>		<td>The parser will validate the document only if a grammar is specified.</td></tr>
-			<tr><th>False:</th>		<td>Validation is determined by the state of the 
-					  					<link anchor="validation">http://xml.org/sax/features/validation</link> feature.</td></tr>
-			<tr><th>Default:</th>	<td>false</td></tr>
-			<tr><th>See:</th>		<td><link anchor="validation">http://xml.org/sax/features/validation</link></td></tr>
-		</table>
-		
-		<anchor name="warn-on-duplicate-attdef"/>
-		<p>http://apache.org/xml/features/validation/warn-on-duplicate-attdef</p>
-		<table>
-			<tr><th>True:</th><td>Warn on duplicate attribute declaration.</td></tr>
-			<tr><th>False:</th><td>Do not warn on duplicate attribute declaration.</td></tr>
-			<tr><th>Default:</th><td>true</td></tr>
-		</table>
-		
-		<anchor name="warn-on-undeclared-elemdef"/>
-		<p>http://apache.org/xml/features/validation/warn-on-undeclared-elemdef</p>
-		<table>
-			<tr><th>True:</th>		<td>Warn if element referenced in content model is not declared.</td></tr>
-			<tr><th>False:</th>		<td>Do not warn if element referenced in content model is not declared.</td></tr>
-			<tr><th>Default:</th>	<td>true</td></tr>
-		</table>
-		
-		<anchor name="allow-java-encodings"/>
-		<p>http://apache.org/xml/features/allow-java-encodings</p>
-		<table>
-			<tr><th>True:</th>		<td>Allow Java encoding names in XMLDecl and TextDecl line.</td></tr>
-			<tr><th>False:</th>		<td>Do not allow Java encoding names in XMLDecl and TextDecl line.</td></tr>
-			<tr><th>Default:</th>	<td>false</td></tr>
-			<tr><th>Note:</th>		<td>A true value for this feature allows the encoding of the file to be 
-					 				  specified as a Java encoding name as well as the standard ISO encoding 
-					 				  name. Be aware that other parsers may not be able to use Java encoding 
-					 				  names. If this feature is set to false, an error will be generated if 
-					 				  Java encoding names are used.</td></tr>			
-		</table>
-		
-		<anchor name="continue-after-fatal-error"/>
-		<p>http://apache.org/xml/features/continue-after-fatal-error</p>
-		<table>
-			<tr><th>True:</th><td>Continue after fatal error.</td></tr>
-			<tr><th>False:</th><td>Stops parse on first fatal error.</td></tr>
-			<tr><th>Default:</th><td>false</td></tr>
-		</table>	
-		
-		<anchor name="load-dtd-grammar"/>
-		<p>http://apache.org/xml/features/nonvalidating/load-dtd-grammar</p>
-		<table>
-			<tr><th>True:</th><td> Will load the DTD Grammar, based on the information provided in DTD, 
-			                       add default attribute information and set the attribute type when parsing.</td></tr>
-			<tr><th>False:</th><td>Will ignore the DTD grammar.</td></tr>
-			<tr><th>Default:</th><td>true</td></tr>
-			<tr><th>Note:</th>		<td>This feature functions only when the validation is turned off.</td></tr>
-		</table>	
-	</s2>
-	<s2 title="DOM Features">
-		<anchor name="defer-node-expansion"/>
-		<p>http://apache.org/xml/features/dom/defer-node-expansion</p>
-		<table>
-			<tr><th>True:</th>		<td>Lazy DOM node expansion.</td></tr>
-			<tr><th>False:</th>		<td>Full DOM node expansion.</td></tr>
-			<tr><th>Default:</th>	<td>true</td></tr>
-			<tr><th>Note:</th>		<td>This feature only applies when the 
-					  				 <link idref="properties" anchor="document-class-name">http://apache.org/xml/properties/dom/document-class-name</link> property is
-					   				 set to a value other than the name of the default document factory.
-					   				 If this feature is set to true, the DOM nodes in the returned 
-					   				 document are expanded as the tree is traversed. This feature allows 
-					   				 the parser to return a document faster than if the tree is fully 
-					   				 expanded during parsing and improves memory usage when the whole 
-					   				 tree is not traversed.</td></tr>
-			<tr><th>See</th>		<td><link idref="properties" anchor="document-class-name">http://apache.org/xml/properties/dom/document-class-name</link></td></tr>
-		</table>	
-		
-		<anchor name="create-entity-ref-nodes"/>
-		<p>http://apache.org/xml/features/dom/create-entity-ref-nodes</p>
-		<table>
-			<tr><th>True:</th>		<td>Create EntityReference nodes in the DOM tree. The EntityReference nodes and their child nodes will be read-only.</td></tr>
-			<tr><th>False:</th>		<td>Do not create EntityReference nodes in the DOM tree. No EntityReference nodes will be created, only the nodes corresponding to their fully expanded sustitution text will be created.</td></tr>
-			<tr><th>Default:</th>	<td>true</td></tr>
-			<tr><th>Note:</th>		<td>This feature only affects the appearance of EntityReference nodes in 
-					 				  the DOM tree. The document will always contain the entity reference 
-					  				 child nodes.</td></tr>
-		</table>	
-		
-		<anchor name="include-ignorable-whitespace"/>
-		<p>http://apache.org/xml/features/dom/include-ignorable-whitespace</p>
-		<table>
-			<tr><th>True:</th>		<td>Includes text nodes that can be 
-										considered "ignorable whitespace" in the DOM tree.</td></tr>
-			<tr><th>False:</th>		<td>Does not include ignorable whitespace in the DOM tree.</td></tr>
-			<tr><th>Default:</th>	<td>true</td></tr>
-			<tr><th>Note:</th>		<td>The only way that the parser can determine if text is ignorable is 
-									   by reading the associated grammar and having a content model for 
-									   the document. When ignorable whitespace text nodes are included in
-									   the DOM tree, they will be flagged as ignorable. The ignorable flag 
-									   can be queried by calling the TextImpl#isIgnorableWhitespace():boolean 
-									   method.</td></tr>
-		</table>	
-		
-		<anchor name="grammar-access"/>
-		<p>http://apache.org/xml/features/domx/grammar-access</p>
-		<table>
-			<tr><th>True:</th>		<td>Creates nodes that describe the grammar in the DOM tree.</td></tr>
-			<tr><th>False:</th>		<td>Does not create create grammar access nodes in the DOM
-   										tree. This setting makes the DOM behave as a standard
-   										DOM Level 1 implementation.</td></tr>
-			<tr><th>Default:</th>		<td>false</td></tr>
-			<tr><th>Note:</th>		<td>The grammar access nodes are appended as children of the
-									   DocumentType node. The grammar is specified as an
-									   XML Schema document tree, whether it was read from a 
-									   document with an associated DTD or XML Schema grammar.
-									   This is currently a violation of the DOM Level 1 
-									   specification. 
-									   <br/><em>**** This is an experimental feature that is not guaranteed </em>
-									   <br/><em>**** to be supported in future versions of
-									   the parser.</em></td></tr>
-		</table>	
-	</s2>
-	<s2 title="SAX Features">
-		<!--
-		<anchor name="use-locator"/>
-		<p>http://xml.org/sax/features/use-locator</p>
-		<table>
-			<tr><th>True:</th>		<td>Provide a Locator using the DocumentHandler setDocumentLocator callback.</td></tr>
-			<tr><th>False:</th>		<td>Explicitly allow the parser not to provide a Locator (but it still may).</td></tr>
-			<tr><th>Default:</th>	<td>true</td></tr>
-			<tr><th>Note:</th>		<td>Xerces-J always provides a Locator to the document handler</td></tr>
-		</table>
-		
-		<anchor name="normalize-text"/>
-		<p>http://xml.org/sax/features/normalize-text</p>
-		<table>
-			<tr><th>True:</th>		<td>Ensure that all consecutive text is returned 
-										in a single callback to the DocumentHandler 
-										characters method.</td></tr>
-			<tr><th>False:</th>		<td>Explicitly allow the parser to split 
-										consecutive text into more than one callback 
-										(but it still may not do so).</td></tr>
-			<tr><th>Default:</th>	<td>true</td></tr>
-			<tr><th>Note:</th>		<td>Xerces-J currently does not support allowing 
-										consecutive text to be buffered and returned 
-										in a single callback to the DocumentHandler 
-										characters method.</td></tr>
-		</table>
-		-->
-		<anchor name='namespace-prefixes'/>
-		<p>http://xml.org/sax/features/namespace-prefixes</p>
-		<table>
-			<tr><th>True:</th>	<td>Report the original prefixed names and attributes used for Namespace declarations.</td></tr>
-			<tr><th>False:</th>	<td>Do not report attributes used for Namespace declarations, and optionally do not report original prefixed names.</td></tr>
-			<tr><th>Default:</th>	<td>true</td></tr>
-			<tr><th>Access:</th>	<td>(parsing) read-only; (not parsing) read/write</td></tr>
-		</table>
-		<anchor name='string-interning'/>
-		<p>http://xml.org/sax/features/string-interning</p>
-		<table>
-			<tr><th>True:</th>	<td>All element names, prefixes, attribute names, Namespace URIs, and local names are internalized using java.lang.String.intern.</td></tr>
-			<tr><th>False:</th>	<td>Names are not necessarily internalized.</td></tr>
-			<tr><th>Default:</th>	<td>false</td></tr>
-			<tr><th>Access:</th>	<td>(parsing) read-only; (not parsing) read/write</td></tr>
-			<tr><th>Note:</th>	<td>Xerces-J does not support interning all strings using the
-						String.intern() method because Xerces-J does its own intern
-						optimizations for String objects.</td></tr>
-		</table>
-	</s2>
-</s1> 
-
diff --git a/docs/feedback.xml b/docs/feedback.xml
deleted file mode 100644
index 3c1d7b0..0000000
--- a/docs/feedback.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="Feedback Procedures">
-	<s2 title="Questions or Comments">
-		<p>For all questions or comments, write to the &javaparsername; mailing list.</p>
-		<p>If you are submitting a bug (and bug reports are definitely appreciated!), 
-			please provide the following information:</p>
-		<ul>
-			<li>Version number of &javaparsername; (&javaparserversion;?) </li>
-			<li>Version number of JDK (1.1.8? 1.2?)</li>
-			<li>Sample XML file that causes the bug</li>
-			<li>Sample Schema file (if required to recreate the bug)</li>
-			<li>Sample DTD file (if required to recreate the bug)</li>			
-		</ul>
-	</s2>
-</s1>
diff --git a/docs/install.xml b/docs/install.xml
deleted file mode 100644
index 98af4b5..0000000
--- a/docs/install.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="Installation">
-	<s2 title="Unpacking the files">
-		<p>&javaparsername; is packaged as a ZIP file for all
-		platforms and operating systems.  You can run the Java
-		<ref>jar</ref> command to unpack the distribution.</p>
-        <ul>
-			<li>jar xf &javaparsername;-bin.&javaparserversion;.zip</li>
-			<li>jar xf &javaparsername;-src.&javaparserversion;.zip</li>
-			<li>This command creates a "&javaparserdirectory;" sub-directory in the current directory containing all the files.</li>
-		</ul>
-	</s2>
-	<s2 title="Files in the binary package release">
-		<table>
-			<tr><td>LICENSE</td><td>License for &javaparsername;</td></tr>
-			<!--<tr><td>README</td><td>Build instructions</td></tr>-->
-			<tr><td>Readme.html</td><td>Web page redirect to docs/html/index.html</td></tr>
-			<!--<tr><td>STATUS</td><td>Project status list</td></tr>-->
-			<tr><td>xerces.jar</td><td>Jar file containing all the parser class files</td></tr>
-			<tr><td>xercesSamples.jar</td><td>Jar file containing all sample class files</td></tr>
-			<tr><td>data/</td><td>Directory containing sample XML data files</td></tr>
-			<tr><td>docs/html/</td><td>Directory containing documentation</td></tr>
-			<tr><td>docs/apiDocs/</td><td>Directory containing Javadoc API for parser framework</td></tr>
-		</table>
-		<note>To use &javaparsername; you do not need the source files. 
-		</note>
-	</s2>
-	<s2 title="Files in the source package release">
-		<table>
-			<tr><td>LICENSE</td><td>License for &javaparsername;</td></tr>
-			<tr><td>Makefile</td><td>Top level Makefile -- read README file before building</td></tr>
-			<tr><td>README</td><td>Build instructions</td></tr>
-			<tr><td>Readme.html</td><td>Web page redirect required for building documentation</td></tr>
-			<tr><td>STATUS</td><td>Current source code status information</td></tr>
-			<tr><td>data/</td><td>Directory containing sample XML data files</td></tr>
-			<tr><td>docs/</td><td>Directory containing documentation, in XML form</td></tr>
-			<tr><td>samples/</td><td>Directory containing source code for samples</td></tr>
-			<tr><td>src/</td><td>Directory containing source code for parser and supplemental APIs</td></tr>
-		</table>
-	</s2>
-</s1>
diff --git a/docs/javapurecheck.xml b/docs/javapurecheck.xml
deleted file mode 100644
index 2971fde..0000000
--- a/docs/javapurecheck.xml
+++ /dev/null
@@ -1,1108 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="JavaPureCheck Output">
-	<s2 title="JavaPureCheck Results">
-<source>###################### JavaPureCheck Report ##########################
-#      
-#      Generated on          : January 26, 2000 10:34:32 AM PST
-#      System Model Version  : jdk11
-#      JavaPureCheck Version : 3.15	
-#      Rule Base Version     : 1.92
-#      
-#      Summary: 
-#      
-#      PURE: 339 	WARNING: 9 	ERROR: 0
-#      
-#      Final Result   :  WARNING
-#      
-######################################################################
-
-Class: org.xml.sax.InputSource
-Status: PURE
-
-Class: org.xml.sax.misc.LexicalHandler
-Status: PURE
-
-Class: org.xml.sax.misc.NamespaceHandler
-Status: PURE
-
-Class: org.xml.sax.misc.DeclHandler
-Status: PURE
-
-Class: org.xml.sax.SAXNotSupportedException
-Status: PURE
-
-Class: org.xml.sax.AttributeList
-Status: PURE
-
-Class: org.xml.sax.SAXNotRecognizedException
-Status: PURE
-
-Class: org.xml.sax.DTDHandler
-Status: PURE
-
-Class: org.xml.sax.ErrorHandler
-Status: PURE
-
-Class: org.xml.sax.DocumentHandler
-Status: PURE
-
-Class: org.xml.sax.SAXException
-Status: PURE
-
-Class: org.xml.sax.helpers.LocatorImpl
-Status: PURE
-
-Class: org.xml.sax.helpers.ConfigurableParserAdapter
-Status: PURE
-
-Class: org.xml.sax.helpers.ParserFactory
-	Warning: method reference: java.lang.Class.forName(java.lang.String)
-	Note: May load impure class
-	Explanation: 	&lt;Explanation required&gt;
-Status: WARNING
-
-Class: org.xml.sax.helpers.AttributeListImpl
-Status: PURE
-
-Class: org.xml.sax.SAXParseException
-Status: PURE
-
-Class: org.xml.sax.Parser
-Status: PURE
-
-Class: org.xml.sax.EntityResolver
-Status: PURE
-
-Class: org.xml.sax.HandlerBase
-Status: PURE
-
-Class: org.xml.sax.Locator
-Status: PURE
-
-Class: org.xml.sax.Configurable
-Status: PURE
-
-Class: org.apache.xml.serialize.HTMLSerializer
-Status: PURE
-
-Class: org.apache.xml.serialize.BaseMarkupSerializer
-Status: PURE
-
-Class: org.apache.xml.serialize.SerializerFactory
-	Warning: method reference: java.lang.Class.forName(java.lang.String)
-	Note: May load impure class
-	Explanation: 	&lt;Explanation required&gt;
-Status: WARNING
-
-Class: org.apache.xml.serialize.Serializer
-Status: PURE
-
-Class: org.apache.xml.serialize.OutputFormat$DTD
-Status: PURE
-
-Class: org.apache.xml.serialize.OutputFormat$Defaults
-Status: PURE
-
-Class: org.apache.xml.serialize.OutputFormat
-	Warning: possible hard-coded path: text/xml
-	Note: Defines a bad path
-	Explanation: 	&lt;Explanation required&gt;
-	Warning: possible hard-coded path: text/plain
-	Note: Defines a bad path
-	Explanation: 	&lt;Explanation required&gt;
-	Warning: possible hard-coded path: application/pdf
-	Note: Defines a bad path
-	Explanation: 	&lt;Explanation required&gt;
-	Warning: possible hard-coded path: text/html
-	Note: Defines a bad path
-	Explanation: 	&lt;Explanation required&gt;
-	Warning: possible hard-coded path: -//W3C//DTD XHTML 1.0 Strict//EN
-	Note: Defines a bad path
-	Explanation: 	&lt;Explanation required&gt;
-Status: WARNING
-
-Class: org.apache.xml.serialize.Method
-Status: PURE
-
-Class: org.apache.xml.serialize.SerializerFactoryImpl
-Status: PURE
-
-Class: org.apache.xml.serialize.HTMLdtd
-	Warning: method reference: java.lang.Class.forName(java.lang.String)
-	Note: May load impure class
-	Explanation: 	&lt;Explanation required&gt;
-Status: WARNING
-
-Class: org.apache.xml.serialize.XMLSerializer
-Status: PURE
-
-Class: org.apache.xml.serialize.XHTMLSerializer
-Status: PURE
-
-Class: org.apache.xml.serialize.ElementState
-Status: PURE
-
-Class: org.apache.xml.serialize.TextSerializer
-Status: PURE
-
-Class: org.apache.xml.serialize.LineSeparator
-Status: PURE
-
-Class: org.apache.xml.serialize.DOMSerializer
-Status: PURE
-
-Class: org.apache.html.dom.HTMLDirectoryElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLTableRowElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLTableColElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLFieldSetElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLModElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLTableSectionElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLDocumentImpl
-	Warning: method reference: java.lang.Class.forName(java.lang.String)
-	Note: May load impure class
-	Explanation: 	&lt;Explanation required&gt;
-Status: WARNING
-
-Class: org.apache.html.dom.NameNodeListImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLStyleElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLBuilder
-Status: PURE
-
-Class: org.apache.html.dom.HTMLFontElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLTableElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLMetaElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLTextAreaElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLPreElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLUListElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLOptionElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLHRElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLLabelElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLTableCaptionElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLBaseFontElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLMenuElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLQuoteElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLObjectElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLSelectElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLFormElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLScriptElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLBRElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLOListElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLImageElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLBaseElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLFrameElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLHtmlElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLParagraphElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLDivElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLLIElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLHeadElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLOptGroupElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLButtonElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLTableCellElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLInputElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLBodyElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLAreaElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLHeadingElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLLegendElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLCollectionImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLFormControl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLParamElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLDOMImplementationImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLTitleElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLMapElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLDListElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLAppletElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLIFrameElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLFrameSetElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLAnchorElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLIsIndexElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.HTMLLinkElementImpl
-Status: PURE
-
-Class: org.apache.html.dom.CollectionIndex
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLDocumentScanner$XMLDeclDispatcher
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLDocumentScanner
-Status: PURE
-
-Class: org.apache.xerces.framework.Version
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLContentSpecNode
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLDocumentScanner$TrailingMiscDispatcher
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLValidator$ContentSpec
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLDTDScanner$EventHandler
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLAttrList
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLParser$NullReader
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLParser$ReaderState
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLDocumentScanner$EventHandler
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLValidator
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLDocumentScanner$PrologDispatcher
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLErrorReporter
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLDocumentScanner$ScannerDispatcher
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLDocumentScanner$EndOfInputDispatcher
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLParser
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLDocumentScanner$ContentDispatcher
-Status: PURE
-
-Class: org.apache.xerces.framework.XMLDTDScanner
-Status: PURE
-
-Class: org.apache.xerces.domx.DOMException
-Status: PURE
-
-Class: org.apache.xerces.domx.XGrammarWriter
-Status: PURE
-
-Class: org.apache.xerces.domx.XGrammarWriter$OutputFormat
-Status: PURE
-
-Class: org.apache.xerces.readers.XMLEntityHandler$EntityReader
-Status: PURE
-
-Class: org.apache.xerces.readers.StreamingCharReader$DeferredError
-Status: PURE
-
-Class: org.apache.xerces.readers.StringReader
-	Warning: method reference: java.lang.Class.forName(java.lang.String)
-	Note: May load impure class
-	Explanation: 	&lt;Explanation required&gt;
-Status: WARNING
-
-Class: org.apache.xerces.readers.UTF8CharReader
-Status: PURE
-
-Class: org.apache.xerces.readers.CharReader
-Status: PURE
-
-Class: org.apache.xerces.readers.XMLDeclRecognizer
-Status: PURE
-
-Class: org.apache.xerces.readers.XCatalog
-Status: PURE
-
-Class: org.apache.xerces.readers.UCSReader
-Status: PURE
-
-Class: org.apache.xerces.readers.DefaultReaderFactory
-Status: PURE
-
-Class: org.apache.xerces.readers.XMLEntityHandler$CharBuffer
-Status: PURE
-
-Class: org.apache.xerces.readers.UTF8Recognizer
-Status: PURE
-
-Class: org.apache.xerces.readers.StreamingCharReader
-Status: PURE
-
-Class: org.apache.xerces.readers.UCSRecognizer
-Status: PURE
-
-Class: org.apache.xerces.readers.XCatalog$Parser
-Status: PURE
-
-Class: org.apache.xerces.readers.UTF8Reader
-Status: PURE
-
-Class: org.apache.xerces.readers.XMLEntityReaderFactory
-Status: PURE
-
-Class: org.apache.xerces.readers.XMLEntityReader
-Status: PURE
-
-Class: org.apache.xerces.readers.XCatalog$Parser$Resolver
-Status: PURE
-
-Class: org.apache.xerces.readers.AbstractCharReader$DeferredError
-Status: PURE
-
-Class: org.apache.xerces.readers.AbstractCharReader
-Status: PURE
-
-Class: org.apache.xerces.readers.MIME2Java
-Status: PURE
-
-Class: org.apache.xerces.readers.UTF8Recognizer$XMLDeclReader
-Status: PURE
-
-Class: org.apache.xerces.readers.EBCDICRecognizer
-Status: PURE
-
-Class: org.apache.xerces.readers.XMLEntityHandler
-Status: PURE
-
-Class: org.apache.xerces.readers.XMLCatalogHandler
-Status: PURE
-
-Class: org.apache.xerces.parsers.RevalidatingDOMParser
-Status: PURE
-
-Class: org.apache.xerces.parsers.SAXParser
-Status: PURE
-
-Class: org.apache.xerces.parsers.DOMParser
-	Warning: method reference: java.lang.Class.forName(java.lang.String)
-	Note: May load impure class
-	Explanation: 	&lt;Explanation required&gt;
-Status: WARNING
-
-Class: org.apache.xerces.validators.datatype.InvalidDatatypeValueException
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.BooleanValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.DecimalValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.IllegalFacetException
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.DatatypeMessageProvider
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.InternalDatatypeValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.UnknownFacetException
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.DatatypeValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.IntegerValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.TimeDurationValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.DoubleValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.IllegalFacetValueException
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.StringValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.FloatValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.TimeInstantValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.datatype.RealValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.CMStateSet
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator$EventHandler
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator$AttributeValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.CMNode
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.SimpleContentModel
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator$AttValidatorENTITY
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.CMLeaf
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator$AttValidatorID
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator$AttValidatorENTITIES
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.CMBinOp
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator$AttValidatorNOTATION
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DFAContentModel
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator$AttValidatorIDREF
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator$AttValidatorIDREFS
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator$AttValidatorNMTOKENS
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.ElementDeclPool
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.CMException
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.CMUniOp
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.EntityPool$RequiredNotation
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator$AttValidatorCDATA
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator$AttValidatorNMTOKEN
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.XMLContentModel
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.InsertableElementsInfo
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator
-                            $AttValidatorENUMERATION
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.DTDValidator$ContentSpecImpl
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.EntityPool
-Status: PURE
-
-Class: org.apache.xerces.validators.dtd.MixedContentModel
-Status: PURE
-
-Class: org.apache.xerces.validators.schema.XSchemaValidator
-                                 $DatatypeValidatorRegistry
-Status: PURE
-
-Class: org.apache.xerces.validators.schema.XSchemaValidator
-Status: PURE
-
-Class: org.apache.xerces.validators.schema.DatatypeContentModel
-Status: PURE
-
-Class: org.apache.xerces.validators.schema.XUtil
-Status: PURE
-
-Class: org.apache.xerces.validators.schema.XSchemaValidator$ErrorHandler
-Status: PURE
-
-Class: org.apache.xerces.validators.schema.SchemaMessageProvider
-Status: PURE
-
-Class: org.apache.xerces.validators.schema.XSchemaValidator$Resolver
-Status: PURE
-
-Class: org.apache.xerces.validators.schema.XSchemaValidator$1
-Status: PURE
-
-Class: org.apache.xerces.utils.StringPool
-Status: PURE
-
-Class: org.apache.xerces.utils.SymbolCache
-Status: PURE
-
-Class: org.apache.xerces.utils.CharDataChunk
-	Warning: method reference: java.lang.Class.forName(java.lang.String)
-	Note: May load impure class
-	Explanation: 	&lt;Explanation required&gt;
-Status: WARNING
-
-Class: org.apache.xerces.utils.ChunkyByteArray
-Status: PURE
-
-Class: org.apache.xerces.utils.NamespacesScope$NamespacesHandler
-Status: PURE
-
-Class: org.apache.xerces.utils.XMLMessages
-Status: PURE
-
-Class: org.apache.xerces.utils.StringHasher
-Status: PURE
-
-Class: org.apache.xerces.utils.StringPool$StringProducer
-Status: PURE
-
-Class: org.apache.xerces.utils.XMLMessageProvider
-Status: PURE
-
-Class: org.apache.xerces.utils.ImplementationMessages
-Status: PURE
-
-Class: org.apache.xerces.utils.ChunkyCharArray
-Status: PURE
-
-Class: org.apache.xerces.utils.NamespacesScope
-Status: PURE
-
-Class: org.apache.xerces.utils.UTF8DataChunk
-	Warning: method reference: java.lang.Class.forName(java.lang.String)
-	Note: May load impure class
-	Explanation: 	&lt;Explanation required&gt;
-Status: WARNING
-
-Class: org.apache.xerces.utils.StringPool$CharArrayRange
-Status: PURE
-
-Class: org.apache.xerces.utils.XMLCharacterProperties
-Status: PURE
-
-Class: org.apache.xerces.msg.XMLMessages
-Status: PURE
-
-Class: org.apache.xerces.msg.SchemaMessages
-Status: PURE
-
-Class: org.apache.xerces.msg.ImplementationMessages
-Status: PURE
-
-Class: org.apache.xerces.msg.DatatypeMessages
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredNotationImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredEntityImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredNode
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredProcessingInstructionImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredDocumentTypeImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.TreeWalkerImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredEntityReferenceImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.NotationImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.events.EventImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.events.MutationEventImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DOMImplementationImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.NodeImpl$EnclosingAttr
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredCommentImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredElementImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DocumentTypeImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.NodeImpl$LEntry
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredElementNSImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.ElementDefinitionImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredTextImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DocumentFragmentImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredDocumentImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredDocumentImpl$IntVector
-Status: PURE
-
-Class: org.apache.xerces.dom.CharacterDataImpl$1
-Status: PURE
-
-Class: org.apache.xerces.dom.CommentImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.NodeIteratorImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DOMExceptionImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.CharacterDataImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.ElementNSImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.AttrNSImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.LCount
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredCDATASectionImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredAttrNSImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DeepNodeListImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.NodeImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.ProcessingInstructionImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.AttrImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.CDATASectionImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.ElementImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredAttrImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.NodeContainer
-Status: PURE
-
-Class: org.apache.xerces.dom.TextImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.EntityReferenceImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DocumentImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.DeferredElementDefinitionImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.NamedNodeMapImpl
-Status: PURE
-
-Class: org.apache.xerces.dom.EntityImpl
-Status: PURE
-
-Class: org.w3c.dom.DocumentType
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLBodyElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLUListElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLLabelElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLObjectElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLOptGroupElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLDivElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLBaseElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLAnchorElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLLIElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLBRElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLTitleElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLFieldSetElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLDOMImplementation
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLFrameSetElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLFrameElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLTableRowElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLTableColElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLScriptElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLHeadingElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLMapElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLTextAreaElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLIFrameElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLDocument
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLModElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLDirectoryElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLMenuElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLButtonElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLTableElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLParagraphElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLHRElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLFontElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLBaseFontElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLLegendElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLStyleElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLOListElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLOptionElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLTableCellElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLFormElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLLinkElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLTableCaptionElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLInputElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLMetaElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLParamElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLPreElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLSelectElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLCollection
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLQuoteElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLHeadElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLAreaElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLAppletElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLHtmlElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLIsIndexElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLImageElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLTableSectionElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLElement
-Status: PURE
-
-Class: org.w3c.dom.html.HTMLDListElement
-Status: PURE
-
-Class: org.w3c.dom.ProcessingInstruction
-Status: PURE
-
-Class: org.w3c.dom.traversal.NodeIterator
-Status: PURE
-
-Class: org.w3c.dom.traversal.NodeFilter
-Status: PURE
-
-Class: org.w3c.dom.traversal.TreeWalker
-Status: PURE
-
-Class: org.w3c.dom.traversal.DocumentTraversal
-Status: PURE
-
-Class: org.w3c.dom.Attr
-Status: PURE
-
-Class: org.w3c.dom.CDATASection
-Status: PURE
-
-Class: org.w3c.dom.DocumentFragment
-Status: PURE
-
-Class: org.w3c.dom.Comment
-Status: PURE
-
-Class: org.w3c.dom.Text
-Status: PURE
-
-Class: org.w3c.dom.DOMImplementation
-Status: PURE
-
-Class: org.w3c.dom.Element
-Status: PURE
-
-Class: org.w3c.dom.DOMException
-Status: PURE
-
-Class: org.w3c.dom.EntityReference
-Status: PURE
-
-Class: org.w3c.dom.events.MutationEvent
-Status: PURE
-
-Class: org.w3c.dom.events.EventListener
-Status: PURE
-
-Class: org.w3c.dom.events.EventTarget
-Status: PURE
-
-Class: org.w3c.dom.events.EventException
-Status: PURE
-
-Class: org.w3c.dom.events.Event
-Status: PURE
-
-Class: org.w3c.dom.events.DocumentEvent
-Status: PURE
-
-Class: org.w3c.dom.Document
-Status: PURE
-
-Class: org.w3c.dom.NodeList
-Status: PURE
-
-Class: org.w3c.dom.Notation
-Status: PURE
-
-Class: org.w3c.dom.NamedNodeMap
-Status: PURE
-
-Class: org.w3c.dom.CharacterData
-Status: PURE
-
-Class: org.w3c.dom.Node
-Status: PURE
-
-Class: org.w3c.dom.Entity
-Status: PURE
-
-Final Result   :  WARNING</source>
-	</s2>
-</s1>
diff --git a/docs/properties.xml b/docs/properties.xml
deleted file mode 100644
index 35dd605..0000000
--- a/docs/properties.xml
+++ /dev/null
@@ -1,132 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="Properties">
-	<s2 title="Setting Features">
-    <anchor name="properties"/>
-		<p>To set a property on either org.apache.xerces.parsers.SAXParser 
-		or org.apache.xerces.parsers.DOMParser, you should use the SAX2 
-		method <code>setProperty(String,Object)</code>. To query a
-		property, use the SAX2 method <code>getProperty(String)</code>.</p>
-		<p>For example, to set the document factory by name:</p>
-<source>DOMParser p=new DOMParser();
-try {        
-  p.setProperty("http://apache.org/xml/properties/dom/document-class-name",
-                "org.apache.xerces.dom.DocumentImpl");
-} catch (SAXException e) {
-  System.out.println("error in setting up parser property");             
-}</source>
-	</s2>
-	
-	<s2 title="General Properties">
-		<!--
-		<anchor name="namespace-sep"/>
-		<p>http://xml.org/sax/properties/namespace-sep</p>
-		<table>
-			<tr><th>Type:</th>		<td>java.lang.String</td></tr>
-			<tr><th>Access:</th>	<td>read-write</td></tr>
-			<tr><th>Desc:</th>		<td>The separator string that will appear between the namespace 
-									URI and the local part of the name when namespace processing is being 
-									performed. If the value is the empty string, the two parts will be 
-									concatenated. </td></tr>
-			<tr><th>  Default:  </th>	<td>""</td></tr>
-			<tr><th>See:</th>		<td><link idref="features" anchor="namespaces">http://xml.org/sax/features/namespaces</link></td></tr>
-		</table>
-		-->
-		
-		<anchor name="xml-string"/>
-		<p>http://xml.org/sax/properties/xml-string</p>
-		<table>
-			<tr><th>Type:</th>		<td>java.lang.String</td></tr>
-			<tr><th>Access:</th>	<td>read-only</td></tr>
-			<tr><th>Desc:</th>		<td>Get the string of characters associated with the current event. If the 
-									   parser recognizes and supports this property but is not currently 
-									   parsing text, it should return null.</td></tr>
-			<tr><th>Note:</th>		<td>This property is currently not supported because the contents of the 
-   										XML string returned by this property is not well defined.</td></tr>
-		</table>
-	</s2>
-	
-	<s2 title="DOM Parser Properties">
-		<anchor name="current-element-node"/>
-		<p>http://apache.org/xml/properties/dom/current-element-node</p>
-		<table>
-			<tr><th>Type:</th>		<td>org.w3c.dom.Node</td></tr>
-			<tr><th>Access:</th>	<td>read-only</td></tr>
-			<tr><th>Desc:</th>		<td>The current DOM element node while parsing.</td></tr>
-			<tr><th>Note:</th>		<td>This property is useful for determining the location 
-									with a DOM document when an error occurs.</td></tr>
-			<tr><th>See:</th>		<td><link anchor="dom-node">http://xml.org/sax/properties/dom-node</link></td></tr>
-		</table>
-		
-		<anchor name="document-class-name"/>
-		<p>http://apache.org/xml/properties/dom/document-class-name</p>
-		<table>
-			<tr><th>Type:</th>		<td>java.lang.String</td></tr>
-			<tr><th>Access:</th>	<td>read-write</td></tr>
-			<tr><th>Desc:</th>		<td>The fully qualified class name of the DOM 
-									implementation. The implementation used must 
-									have a zero argument constructor.</td></tr>
-			<tr><th>Default:</th>	<td>"org.apache.xerces.dom.DocumentImpl"</td></tr>
-			<tr><th>Note:</th>		<td>When the document class name is set to a value other 
-									than the name of the default document factory, the 
-									deferred node expansion feature does not work. </td></tr>
-			<tr><th>See:</th>		<td><link idref="features" anchor="defer-node-expansion">http://apache.org/xml/features/dom/defer-node-expansion</link></td></tr>
-		</table>
-	</s2>
-	
-	<s2 title="SAX Parser Properties">
-		<!--
-		<anchor name="DeclHandler"/>
-		<p>http://xml.org/sax/handlers/DeclHandler</p>
-		<table>
-			<tr><th>Type:</th>		<td>org.xml.sax.misc.DeclHandler</td></tr>
-			<tr><th>Access:</th>	<td>read-write</td></tr>
-			<tr><th>Desc:</th>		<td>Set the handler for DTD declarations.</td></tr>
-		</table>
-		
-		<anchor name="LexicalHandler"/>
-		<p>http://xml.org/sax/handlers/LexicalHandler</p>
-		<table>
-			<tr><th>Type:</th>		<td>org.xml.sax.misc.LexicalHandler</td></tr>
-			<tr><th>Access:</th>	<td>read-write</td></tr>
-			<tr><th>Desc:</th>		<td>Set the handler for lexical parsing events.</td></tr>
-		</table>
-		
-		<anchor name="NamespaceHandler"/>
-		<p>http://xml.org/sax/handlers/NamespaceHandler</p>
-		<table>
-			<tr><th>Type:</th>		<td>org.xml.sax.misc.NamespaceHandler</td></tr>
-			<tr><th>Access:</th>	<td>read-write</td></tr>
-			<tr><th>Desc:</th>		<td>Set the handler for lexical parsing events.</td></tr>
-		</table>
-		-->
-		<anchor name="declaration-handler"/>
-		<p>http://xml.org/sax/properties/declaration-handler</p>
-		<table>
-			<tr><th>Type:</th>		<td>org.xml.sax.ext.DeclHandler</td></tr>
-			<tr><th>Access:</th>	<td>read-write</td></tr>
-			<tr><th>Desc:</th>		<td>Set the handler for DTD declarations.</td></tr>
-		</table>
-		
-		<anchor name="lexical-handler"/>
-		<p>http://xml.org/sax/properties/lexical-handler</p>
-		<table>
-			<tr><th>Type:</th>		<td>org.xml.sax.ext.LexicalHandler</td></tr>
-			<tr><th>Access:</th>	<td>read-write</td></tr>
-			<tr><th>Desc:</th>		<td>Set the handler for lexical parsing events.</td></tr>
-		</table>
-
-		<anchor name="dom-node"/>
-		<p>http://xml.org/sax/properties/dom-node</p>
-		<table>
-			<tr><th>Type:</th>		<td>org.w3c.dom.Node</td></tr>
-			<tr><th>Access:</th>	<td>(parsing) read-only; (not parsing) read/write</td></tr>
-			<tr><th>Desc:</th>		<td>The DOM node currently being visited, 
-									if SAX is being used as a DOM iterator. 
-									If the parser recognizes and supports this property but is 
-									not currently visiting a DOM node, it should return null.</td></tr>
-		</table>
-		
-	</s2>
-</s1>
diff --git a/docs/readme.xml b/docs/readme.xml
deleted file mode 100644
index cf835b6..0000000
--- a/docs/readme.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="&javaparsernamelong; Readme">
-	<s2 title="&javaparsernamelong; &javaparserversion; Release">
-		<p>The &javaparsernamelong; &javaparserversion; supports 
-		<jump href="http://www.w3.org/TR/1998/REC-xml-19980210">XML 1.0</jump> 
-		recommendation and contains advanced parser functionality, such as 
-		<jump href="http://www.w3.org/XML/Group/Schemas.html">XML Schema</jump>, 
-		<jump href="http://www.w3.org/TR/DOM-Level-2/">DOM Level 2 version 1.0</jump>, and 
-		<jump href="http://www.megginson.com/SAX/">SAX Version 2</jump>, 
-		in addition to supporting the industry-standard 
-		<jump href="http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core.html">DOM Level 1</jump> and 
-		<jump href="http://www.megginson.com/SAX/SAX1/">SAX version 1</jump>
-		APIs.</p>
-        <p>
-        Note that because some of the standards
-		are still not complete, the stable API will definitely be 
-		different from its current form in &javaparsername; &javaparserversion;. 
-		This is your chance to give us 
-		feedback on the features that are important to you, and let us know
-		whether the APIs that we are providing are the right ones. Please 
-		direct your feedback to the &javaparsername; mailing list.</p>
-
-	</s2>
-	<s2 title="License Information">
-		<p>The &javaparsername; &javaparserversion; release is available in both source code
-		and precompiled binary (JAR files) form. Both &javaparsername; 
-                packages are made available under the <jump href='../../LICENSE'>Apache
-                Software License</jump>.
-                </p>
-	</s2>
-	<s2 title="Applications of the &javaparsername; Parser">
-		<p>The rich generating and validating capabilities allow the &javaparsername; 
-		Parser to be used for: </p>
-		<ul>
-			<li>Building XML-savvy Web servers. </li>
-			<li>The next generation of vertical applications which will use 
-				XML as their data format. </li>
-			<li>On-the-fly validation for creating XML editors. </li>
-			<li>Ensuring the integrity of e-business data expressed in XML. </li>
-			<li>Building truly internationalized XML applications. </li>
-		</ul>
-	</s2>
-	<s2 title="XML Schema (alpha) Support">
-		<p>This release includes preliminary support for the W3C XML Schema 
-		Language. The <link idref="schema">Schema</link> page contains a 
-		complete description of the 
-		schema capabilities of this release. We intend to track the W3C XML 
-		Schema Language in subsequent updates of &javaparsername;.</p>
-	</s2>
-	<s2 title="DOM Level 2 (beta) Support">
-		<p>This release includes support for the 
-		<jump href="http://www.w3.org/TR/WD-DOM-Level-2">DOM Level 2</jump>.
-                As of this writing, the DOM Level 2 specification is now a
-                Candidate Recommendation.</p>
-	</s2>
-	<s2 title="SAX 2 Support">
-		<p>This release includes support for the <jump href="http://www.megginson.com/SAX/">
-		SAX Version 2</jump> API&apos;s which have been finalized.</p>
-	</s2>
-	<s2 title="Configuration Mechanism">
-		<p>&javaparsername; &javaparserversion; uses a collection of methods to configure 
-		various settings in the parser. This release includes a new mechanism 
-		for setting parser switches. This mechanism uses the SAX2 configuration
-		methods that are part of the XMLReader interface. We have defined a series 
-		of <link idref="properties">properties</link> and 
-		<link idref="features">features</link> for the &javaparsername; 
-		options. </p>
-	</s2>
-</s1>
diff --git a/docs/releases.xml b/docs/releases.xml
deleted file mode 100644
index c8b1de6..0000000
--- a/docs/releases.xml
+++ /dev/null
@@ -1,185 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="Releases">
-    <s2 title='August 28, 2000'>
-        <ul>
-           <li>Merged redundant Attribute validators inner classes with the data type validators. [jeffreyr]</li>
-           <li>Fixed namespaces bugs for endElement method in SAX. [jeffreyr]</li>
-           <li>Fixed misc. Schema Datatype bugs. [jeffreyr]</li>
-           <li>Fixed misc. DOM implementation bugs. [lehors]</li>
-           <li>Fixed Makefiles and documentations. [andyc]</li>
-           <li>Added "any" with "processContents='lax|skip'" support for Schema. [ericye]</li>           
-           <li>Added feature "load-dtd-grammar" [ericye]</li>
-           <li>Fixed a bug in reset() method of XMLValidator. [ericye]</li>
-           <li>Fixed misc. Schema Structures bugs. [ericye]</li>
-        </ul>
-    </s2>
-    <s2 title='July 26, 2000'>
-        <ul>
-           <li>Added "anyAttribute" support for Schema. [ericye]</li>           
-           <li>Added "xsi:type" support for Schema. [ericye]</li>
-           <li>Added full equivClass support for Schema. [ericye]</li>
-           <li>Fixed "form" attribute behavior to be fully compilant with Schema Spec. [ericye]</li>
-           <li>Fixed "xml:space" bug in DTD validation. [ericye, andyc]</li>
-           <li>Expanded "any" element support to model groups. [ericye]</li>
-           <li>Fixed "any" element bugs when there are multilple URIs. [ericye]</li>
-           <li>Cleaned up XMLValidator. [ericye]</li>
-           <li>Fixed misc. Schema bugs. [ericye]</li>
-           <li>Fixed resolving Schema location bug in XMLValidator. [David.Blankenship@kla_tencor.com, ericye]</li>
-	   <li>Fixed for BUG:SAXParser endElement reports incorrect local name. [jeffreyr]</li>
-	   <li>Fixed DOM Java Serialization-previous fix did not work. [jeffreyr]</li>
-	   <li>Added testcase under test to test DOM Java Serialization. [jeffreyr]</li>
-	   <li>Added James Duncan fix suggestion to not compile RevalidatingDOMParser. [James Duncan, jeffreyr]</li> 
-	   <li>Miscelanous DOM enhancements [lehors]. </li>
-	   <li>Fixed parameterizes entities in XMLDTDScanner. [jeffreyr]</li>
-	   <li>Fixed bug reported by Philippe MOUAWAD, on XMLContentSpec toString method. [jeffreyr]</li>
-	   <li>Fixed problem with DTD validation when namespace is supported is on. [andyc,ericye]</li>
-	   <li>Fixed bug reported by Michael Brundage in StringReader. [jeffreyr]</li>
-        </ul>
-    </s2>
-    <s2 title='June 21, 2000'>
-        <ul>
-           <li>Added "any" element content support for Schema [andyc]</li>
-           <li>Fixed adjacent text nodes bug in deferred DOM [andyc]</li>
-           <li>Fixed namespace URI bug in deferred DOM [andyc]</li>
-           <li>Fixed null document type node bug [andyc]</li>
-           <li>Fixed StringReader index out of bounds exception bug [andyc]</li>
-           <li>Turned on namespace support in all parsers, by default [andyc]</li>
-           <li>Added feature to allow Schema support to be turned off [andyc]</li>
-           <li>Fixed SAX2 DeclHandler, LexicalHandler callbacks [andyc]</li>
-           <li>Fixed DOM serialization [jeffreyr]</li>
-           <li>Fixed datatype enumeration bugs [jeffreyr]</li>
-           <li>Fixed datatype pattern bugs [jeffreyr]</li>
-           <li>Fixed datatype min/maxLength bugs [jeffreyr]</li>
-           <li>Modified samples to include additional switches [jeffreyr]</li>
-           <li>Fixed lexical comparison for string/qname datatypes [jeffreyr]</li>
-           <li>Added regular expression character class subtraction [tkent@jp.ibm.com]</li>
-           <li>Fixed regular expression bugs [tkent@jp.ibm.com]</li>
-           <li>Added URI class [paul.eng@iclick.com]</li>
-           <li>Fixed import/include Schema bug [ericye]</li>
-           <li>Fixed lots of Schema bugs [ericye]</li>
-        </ul>
-    </s2>
-    <s2 title='June 5, 2000'>
-        <ul>
-           <li>Added Schema include/import [ericye]</li>
-           <li>Performance tuning [ericye, andyc]</li>
-           <li>Added Ant support to build process [abagchi]</li>
-           <li>Re-architecture Schema datatypes [jeffreyr]</li>
-           <li>Re-organized docs directory to get FOP to work[abagchi, jeffreyr]</li>
-           <li>Fixed Dynamic validation bug [ericye]</li>
-           <li>Fixed Grammar access bug [ericye, andyc]</li>
-	   <li>Fixed Miscellaneous bugs  [ericye, andyc, jeffreyr]</li> 
-	   <li>Added JAXP to build, updated JAXP files [lehors]</li>
-           <li>Added a DOM from scratch and Serializer sample [jeffreyr]</li>
-           <li>Fixed NodeImpl supports nullpointer bug in Samples [lehors]</li>
-           <li>Fixed a bug in cloning default attribute</li>
-        </ul>
-    </s2>
-    <s2 title='May 19, 2000'>
-        <ul>
-           <li>Reworked internals for XML Schema support [andyc, ericye, 
-	       jeffreyr]</li>
-	   <li>Updated XML Schema support to April working draft [ericye, 
-	       jeffreyr]</li>
-	   <li>Changed code to notify error handler of content model 
-	       validation errors before calling endElement [lehors]</li>
-        </ul>
-    </s2>
-    <s2 title='May 9, 2000'>
-        <ul>
-           <li>Upgraded to SAX 2.0. [lehors]</li>
-           <li>Added support for WML DOM. [david]</li>
-           <li>Preliminary work for full schema support.
-              [andyc, gmarcy, jefreyr, ericye]</li>
-           <li>Reorganized DOM classes to use much less memory. [lehors]</li>
-           <li>Entities and entity reference nodes are now readonly as
-              expected. [lehors]</li>
-           <li>Entity references now have their replacement value when created
-              with createEntityReference. [lehors]</li>
-           <li>Fixed problem in Deferred DOM which made building it N^2 order.
-              [lehors]</li>
-           <li>Fixed handling of elements with IDs in Deferred DOM. [lehors]</li>
-           <li>Added support for namespaces in parameter entities. [lehors]</li>
-           <li>setNodeValue raised an exception when it should simply be a
-              no-op. [lehors]</li>
-           <li>Attributes returned by setNamedItem and setNamedItemNS could not
-              be reused. [lehors]</li>
-           <li>Implemented new DOM Level 2 methods hasAttribute and
-              hasAttributeNS. [lehors]</li>
-           <li>43: importNode now uses createElementNS and createAttributeNS
-              when necessary. [lehors]</li>
-           <li>59: after a first iteration over the whole list, item(index)
-              returned the wrong value. [lehors]</li>
-           <li>60: Fixed. [andyc]</li>
-           <li>62: Cloned attributes return wrong owner element.
-              [awiner@us.oracle.com]</li>
-           <li>Fixed caption element creation pb with HTMLTableElement.
-              [arkin]</li>
-           <li>Improved performance of XML serialize. Added support of
-              encodings and reuse of serializer. [arkin]</li>
-           <li>Updated XML serializer to not be strictly dependent on DOM Level
-              2. [andyc]</li>
-        </ul>
-    </s2>
-    <s2 title="March 8, 2000">
-        <ul>
-            <li>26: Schema lookup disabled when validation is off. [lehors]</li>
-            <li>23: With UCS-4 and UTF-16 encodings, 0xD characters are now properly normalized.[gmarcy]</li>
-            <li>27: SAX2 http://xml.org/sax/features/namespaces - default set to true. [pier]</li>
-            <li>28: Fixed error in setNamespaces javadoc [elharo@metalab.unc.edu]</li>
-            <li>33: Relaxed restraint of xml:space attribute for XHTML DTDs [david-b@pacbell.net]</li>
-            <li>34: SAX 2.0beta2 changes accepted. [rpfeiffe]</li>
-            <li>35: Fixed getLength() to always return the right value[lehors]</li>
-            <li>36: Fixed setPrefix() to update nodeName[lehors]</li>
-        </ul>
-    </s2>
-    <s2 title="February 8, 2000">
-        <ul>
-            <li>Removed hard-coded strings to enable national language support (NLS) [jeffreyr,lehors,rip]</li>
-            <li>Update for SAX2beta [andyc]</li>
-            <li>Add new feature <code>http://apache.org/xml/features/dom/include-ignorable-whitespace</code> [andyc]</li>
-            <li>ChunkyByteArray - needed resize chunk array for large files [andyc] </li>
-            <li>UTF8DataChunk - memory perf fix [andyc] </li>
-            <li>DOM L1 - cache node children length to accelerate <code>Node#item()</code>[andyc]</li>
-            <li>DOM L1 - Off by one error in DeferredDocumentImpl [jflight@impresse.com]</li>
-            <li>DOM L1 - Slight refactoring of DOM to save memory [lehors]</li>   
-            <li>Schema datatypes - add binary &amp; URI, update
-            decimal &amp; String [twl]</li>
-            <li>Schema datatypes - allow StringValidator to validate maxLength &amp; enumeration facets [gtj@peakin.com]</li>
-            <li>Schema datatypes - timeDuration &amp; timeInstant validators [gtj@peakin.com]</li>
-            <li>Schema functionality - allow schema lookup via installed entity resolver [gtj@peakin.com]</li>
-            <li>Schema bug fixes (reportSchemaError &amp; integer subtype registration) [gtj@peakin.com]</li>
-            <li>Serializer bug on CData sections [arkin] </li>
-            <li>Serializers now prints PUBLIC/SYSTEM id [arkin]</li>
-            <li>HTMLTableElementImpl - Empty cell no longer created
-            when adding a row [arkin]</li>
-            <li>DOM L2 - TreeWalkerImpl didn't iterate backwards properly [bmj01@club-internet.fr]</li>
-            <li>DOM L2 - Tracking the candidate recommendation [lehors]</li>
-            <li>DOM L2 Namespace bug fixes [rip, lehors]</li>
-            <li>DOM L2 API moved to org.w3c.dom where it belongs
-            [rip]</li>
-            <li>DOMMemTest [lehors]</li>
-        </ul>
-    </s2>
-    <s2 title="December 31, 1999">
-        <ul>
-            <li>Include documentation in the repository.</li>
-            <li>Switch packaging to jar files from .zip and .tar.gz files.</li>
-            <li>StreamingCharReader for stream based applications.</li>
-            <li>Assaf Arkin's serialization package.</li>
-            <li>Assaf Arkin's HTML DOM Level 1 classes.</li>
-            <li>Performance improvements.</li>
-            <li>Bug fixes.</li>
-        </ul>
-    </s2>
-	<s2 title="November 5, 1999">
-		<ul>
-			<li>Created initial code base from IBM's XML4J.</li>
-			<li>Modified documentation to reflect new name (Xerces)</li>
-		</ul>
-	</s2>
-
-
-</s1>
diff --git a/docs/sam-domcount.xml b/docs/sam-domcount.xml
deleted file mode 100644
index e479024..0000000
--- a/docs/sam-domcount.xml
+++ /dev/null
@@ -1,110 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="SAX/DOMCount Samples">
-	<s2 title="Running SAXCount and DOMCount">
-		<p>SAXCount and DOMCount invoke the parser 
-		on an XML document, and print out information about the 
-		document. By default, SAXCount creates a non-validating 
-		SAX parser and DOMCount creates a validating DOM parser. 
-		They both count the number of elements, attributes, text characters, 
-		and ignorable whitespace characters in the document and display the 
-		amount of time it takes to complete the task. </p>
-		<p>The command lines below expect 
-		the current directory to be the directory containing the JAR file.</p>
-		<p>Requirements:</p>
-		<ul>
-			<li>&javaparsername; is loaded on your computer.</li>
-			<li>JDK is loaded on your computer.</li>
-		</ul>
-		<p>Source code: </p>
-		<ul>
-			<li>SAXCount.java</li>
-			<li>DOMCount.java</li>
-		</ul>
-	</s2>
-
-	<s2 title="SAXCount">
-		<p><em>To run SAXCount:</em></p>
-		<ol>
-			<li>open up a MS-DOS command line window</li>
-			<li>set the path to the jdk\bin directory</li>
-			<li>change directory to the latest &javaparserdirectory; directory</li>
-			<li>invoke the <code>SAXCount</code> sample</li>
-		</ol>
-		<p><em>On Windows:</em></p>
-		<p>The easiest way to do this is to create a .bat file using the 
-		Notepad editor. Then the <code>SAXCount</code> can be invoked by double clicking 
-		on the file name or icon. The following command lines assume that 
-		both the jdk and the &javaparserdirectory; directories are located directly below 
-		the c: drive.</p>
-<source>set PATH=%PATH%;c:\jdk1.1.8\bin
-set CLASSPATH=%CLASSPATH%;c:\&javaparserdirectory;\xerces.jar;c:\&javaparserdirectory;\xercesSamples.jar
-cd c:\&javaparserdirectory;
-java sax.SAXCount data/personal.xml</source>
-
-		<p><em>Switches:</em></p>
-		<p>SAXCount also allows you to change the default behavior using the 
-		following command line flags: </p>
-		<ul>
-			<li>-p Specify the parser class to be used.
-			<br/>The available parsers are:</li>
-			<ul>
-				<li>org.apache.xerces.parsers.SAXParser [default parser]</li>
-			</ul>
-			<li>-h Print SAXCount help information. [default is no help]</li>
-			<li>-v Turn on validation</li>
-		</ul>
-		<p>Running SAXCount with the default settings is equivalent to 
-		running SAXCount like this (type this in as one long command line): </p>
-<source>java sax.SAXCount -p org.apache.xerces.parsers.SAXParser 
-    data/personal.xml </source>
-		<p>Bringing up the help information: </p>
-<source>java sax.SAXCount -h </source>
-		<note>Parse your own XML file instead of data/personal.xml</note>
-	</s2>
-	
-	<s2 title="DOMCount">
-		<p><em>To run DOMCount:</em></p>
-		<ol>
-			<li>open up a MS-DOS command line window</li>
-			<li>set the path to the jdk\bin directory</li>
-			<li>change directory to the latest &javaparserdirectory; directory</li>
-			<li>invoke the <code>DOMCount</code> sample</li>
-		</ol>
-		
-		<p><em>On Windows:</em></p>
-		<p>The easiest way to do this is to create a .bat file using the 
-		Notepad editor. Then the <code>DOMCount</code> can be invoked by double clicking 
-		on the file name or icon. The following command lines assume that 
-		both the jdk and the &javaparserdirectory; directories are located directly below 
-		the c: dirve.</p>
-<source>set PATH=%PATH%;c:\jdk1.1.8\bin
-set CLASSPATH=%CLASSPATH%;c:\&javaparserdirectory;\xerces.jar;c:\&javaparserdirectory;\xercesSamples.jar
-cd c:\&javaparserdirectory;
-java dom.DOMCount data/personal.xml</source>
-
-		<p><em>Switches:</em></p>
-		<p>DOMCount also allows you to change the default behavior via the 
-		following command line flags: </p>
-		<ul>
-			<li>-p Specify the parser class to be used.
-			<br/>The available parsers are:</li>
-			<ul>
-				<li>dom.wrappers.DOMParser [default parser]</li>
-			</ul>
-			<li>-h Print DOMCount help information. [default is no help]</li>
-		</ul>
-		<p>Running DOMCount with the default settings is equivalent to running 
-		<code>DOMCount</code> like this (type this in as one long command line): </p>
-
-<source>java dom.DOMCount -p dom.wrappers.DOMParser 
-    data/personal.xml </source>
-		<p>Bringing up the help information: </p>
-<source>java dom.DOMCount -h</source>
-
-		<note>Parse your own XML file instead of data/personal.xml</note>
-
-
-	</s2>
-</s1>
diff --git a/docs/sam-domfilter.xml b/docs/sam-domfilter.xml
deleted file mode 100644
index 7fba03f..0000000
--- a/docs/sam-domfilter.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="DOMFilter Sample">
-	<s2 title="Running DOMFilter">
-		<p><code>DOMFilter</code> parses an XML document, searching for specific elements 
-		by name, or elements with specific attributes.</p>
-		<p>Requirements:</p>
-		<ul>
-			<li>&javaparsername; is loaded on your computer.</li>
-			<li>JDK is loaded on your computer.</li>
-		</ul>
-		<p>Source code: </p>
-		<ul>
-			<li>DOMFilter.java</li>
-		</ul>
-	</s2>
-	
-	<s2 title="DOMFilter">
-		<p><em>To run DOMFilter:</em></p>
-		<ol>
-			<li>open up a MS-DOS command line window</li>
-			<li>set the path to the jdk\bin directory</li>
-			<li>change directory to the latest &javaparserdirectory; directory</li>
-			<li>invoke the <code>DOMFilter</code> sample</li>
-		</ol>
-		
-		<p><em>On Windows:</em></p>
-		<p>The easiest way to do this is to create a .bat file using the 
-		Notepad editor. Then the <code>DOMFilter</code> can be invoked by double clicking 
-		on the file name or icon. The following command lines assume that 
-		both the jdk and the &javaparserdirectory; directories are located directly below 
-		the c: dirve.</p>
-<source>set PATH=%PATH%;c:\jdk1.1.8\bin
-set CLASSPATH=%CLASSPATH%;c:\&javaparserdirectory;\xerces.jar;c:\&javaparserdirectory;\xercesSamples.jar
-cd c:\&javaparserdirectory;
-java dom.DOMFilter data/personal.xml</source>
-
-		<p><em>Switches:</em></p>
-		<p><code>DOMFilter</code> also allows you to change the default behavior using the 
-		following command line flags (type this in as one long command line): </p>
-		<ul>
-			<li>-p Specify the parser class to be used.
-			<br/>The available parsers are:</li>
-			<ul>
-				<li>dom.wrappers.DOMParser [default parser]</li>
-			</ul>
-			<li>-h Print DOMCount help information. [default is no help]</li>
-			<li>-e Specify the name of the element to search for. 
-			[defaults to matching all elements]</li>
-			<li>-a Specify the name of the attribute to search for. 
-			[defaults to matching all attributes]</li>
-		</ul>
-		<p>Running <code>DOMFilter</code> with the default settings is 
-		equivalent to running 
-		<code>DOMFilter</code> like this: </p>
-
-<source>java dom.DOMFilter -p dom.wrappers.DOMParser 
-    data/personal.xml </source>
-	
-		<p>Bringing up the help information: </p>
-<source>java dom.DOMFilter -h</source>
-	
-		<p>Searching for elements: </p>
-<source>java dom.DOMFilter -e family data/personal.xml</source>
-	
-		<p>Search for attributes: </p>
-<source>java dom.DOMFilter -a subordinates data/personal.xml</source>
-
-		<note>Parse your own XML file instead of data/personal.xml</note>
-
-
-	</s2>
-</s1>
diff --git a/docs/sam-domwriter.xml b/docs/sam-domwriter.xml
deleted file mode 100644
index 28634de..0000000
--- a/docs/sam-domwriter.xml
+++ /dev/null
@@ -1,147 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="SAX/DOMWriter Samples">
-	<s2 title="Running SAXWriter and DOMWriter">
-		<p><code>SAXWriter</code> and <code>DOMWriter</code> parse your input file, 
-		and print it out in XML format.  A command line option can be used to 
-		print in a "canonical" XML format so the output can be used to compare 
-		XML documents. SAXWriter and DOMWriter also display any errors or 
-		warnings that occurred during the parse.</p>
-		<p><code>DOMWriter</code> provides a -e switch to set the output 
-		Java encoding. </p>
-		<p>The command lines below expect the current directory to be the 
-		directory containing the JAR file.</p>
-		<p>Requirements:</p>
-		<ul>
-			<li>&javaparsername; is loaded on your computer.</li>
-			<li>JDK is loaded on your computer.</li>
-		</ul>
-		<p>Source code: </p>
-		<ul>
-			<li>SAXWriter.java</li>
-			<li>DOMWriter.java</li>
-		</ul>
-	</s2>
-
-	<s2 title="SAXWriter">
-		<p><em>To run SAXWriter:</em></p>
-		<ol>
-			<li>open up a MS-DOS command line window</li>
-			<li>set the path to the jdk\bin directory</li>
-			<li>change directory to the latest &javaparserdirectory; directory</li>
-			<li>invoke the <code>SAXWriter</code> sample</li>
-		</ol>
-		<p><em>On Windows:</em></p>
-		<p>The easiest way to do this is to create a .bat file using the 
-		Notepad editor. Then the <code>SAXWriter</code> can be invoked by double clicking 
-		on the file name or icon. The following command lines assume that 
-		both the jdk and the &javaparserdirectory; directories are located directly below 
-		the c: drive.</p>
-<source>set PATH=%PATH%;c:\jdk1.1.8\bin
-set CLASSPATH=%CLASSPATH%;c:\&javaparserdirectory;\xerces.jar;c:\&javaparserdirectory;\xercesSamples.jar
-cd c:\&javaparserdirectory;
-java sax.SAXWriter data/personal.xml</source>
-
-		<p><em>Switches:</em></p>
-		<p>SAXCount also allows you to change the default behavior using the 
-		following command line flags: </p>
-		<ul>
-			<li>-p Specify the parser class to be used.
-			<br/>The available parsers are:</li>
-			<ul>
-				<li>org.apache.xerces.parsers.SAXParser [default parser]</li>
-			</ul>
-			<li>-h Print SAXWriter help information. [default is no help]</li>
-			<li>-c Output in canonical format. [default is normal format] </li>
-		</ul>
-		<p>Running <code>SAXWriter</code> with the default settings is equivalent to 
-		running <code>SAXWriter</code> like this (type this in as one long command line): </p>
-<source>java sax.SAXWriter -p org.apache.xerces.parsers.SAXParser 
-    data/personal.xml </source>
-	
-		<p>Bringing up the help information: </p>
-<source>java sax.SAXWriter -h </source>
-
-		<p>Print in canonical format: </p>
-<source>java sax.SAXWriter -c  data/personal.xml</source>
-
-		<note>Parse your own XML file instead of data/personal.xml</note>
-	</s2>
-	
-	<s2 title="DOMWriter">
-		<p><em>To run DOMWriter:</em></p>
-		<ol>
-			<li>open up a MS-DOS command line window</li>
-			<li>set the path to the jdk\bin directory</li>
-			<li>change directory to the latest &javaparserdirectory; directory</li>
-			<li>invoke the <code>DOMWriter</code> sample</li>
-		</ol>
-		
-		<p><em>On Windows:</em></p>
-		<p>The easiest way to do this is to create a .bat file using the 
-		Notepad editor. Then the <code>DOMWriter</code> can be invoked by double clicking 
-		on the file name or icon. The following command lines assume that 
-		both the jdk and the &javaparserdirectory; directories are located directly below 
-		the c: dirve.</p>
-<source>set PATH=%PATH%;c:\jdk1.1.8\bin
-set CLASSPATH=%CLASSPATH%;c:\&javaparserdirectory;\xerces.jar;c:\&javaparserdirectory;\xercesSamples.jar
-cd c:\&javaparserdirectory;
-java dom.DOMWriter data/personal.xml</source>
-
-		<p><em>Switches:</em></p>
-		<p>DOMCount also allows you to change the default behavior via the 
-		following command line flags (type this in as one long command line): </p>
-		<ul>
-			<li>-p Specify the parser class to be used.
-			<br/>The available parsers are:</li>
-			<ul>
-				<li>dom.wrappers.DOMParser [default parser]</li>
-			</ul>
-			<li>-h Print DOMWriter help information. [default is no help]</li>
-			<li>-c Output in canonical format. [default is normal format]</li>
-			<li>-e encodingName Output using the specified encoding. [default is UTF8]</li>			
-		</ul>
-		<p>Running <code>DOMWriter</code> with the default settings is equivalent to running 
-		<code>DOMWriter</code> like this: </p>
-
-<source>java dom.DOMWriter -p dom.wrappers.DOMParser 
-    data/personal.xml </source>
-	
-		<p>Bringing up the help information: </p>
-<source>java dom.DOMWriter -h</source>
-
-		<p>Searching for elements: </p>
-<source>java dom.DOMWriter -c data/personal.xml</source>
-
-		<p>Running DOMWriter with the -e switch and no encoding specified 
-		will print out a list of valid encoding names: </p>
-<source>java dom.DOMWriter -e</source>
-
-		<p>Prints the following: </p>
-<source>Java Encoding one of (case sensitive):
-  Default
-  8859_1 8859_2 8859_3 8859_4 8859_5 8859_6 8859_7
-  8859_8 8859_9 Cp037 Cp273 Cp277 Cp278 Cp280 
-  Cp284 Cp285 Cp297 Cp420 Cp424 Cp437 Cp500
-  Cp737 Cp775 Cp838 Cp850 Cp852 Cp855 Cp856
-  Cp857 Cp860 Cp861 Cp862 Cp863 Cp864 Cp865
-  Cp866 Cp868 Cp869 Cp870 Cp871 Cp874 Cp875
-  Cp918 Cp921 Cp922 Cp930 Cp933 Cp935 Cp937
-  Cp939 Cp942 Cp948 Cp949 Cp950 Cp964 Cp970
-  Cp1006 Cp1025 Cp1026 Cp1046 Cp1097 Cp1098 Cp1112
-  Cp1122 Cp1123 Cp1124 Cp1250 Cp1251 Cp1252 Cp1253
-  Cp1254 Cp1255 Cp1256 Cp1257 Cp1258 Cp1381 Cp1383
-  Cp33722 MS874 DBCS_ASCII DBCS_EBCDIC EUC EUCJIS GB2312
-  GBK ISO2022CN_CNS ISO2022CN_GB JIS JIS0208 KOI8_R KSC5601
-  MS874 SJIS SingleByte Big5 CNS11643 MacArabic
-  MacCentralEurope MacCroatian MacCyrillic MacDingbat
-  MacGreek MacHebrew MacIceland MacRoman MacRomania
-  MacSymbol MacThai MacTurkish MacUkraine SJIS Unicode 
-  UnicodeBig UnicodeLittle UTF8</source>
-
-		<note>Parse your own XML file instead of data/personal.xml</note>
-
-
-	</s2>
-</s1>
diff --git a/docs/sam-iterator.xml b/docs/sam-iterator.xml
deleted file mode 100644
index 34f4b50..0000000
--- a/docs/sam-iterator.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="IteratorView Sample">
-	<s2 title="IteratorView">
-		<p>The <code>IteratorView</code> is an interactive UI sample that displays the DOM tree. It
-		shows the progress of the iteration by moving the selection within the DOM tree.
-		Buttons act as a control panel, allowing the user to interactively iterate through
-		the tree,  remove nodes, add nodes, and view the results immediately in the tree.</p>
-		<p>The <code>IteratorView</code> uses an example filter, <code>NameNodeFilter</code>, that can be controlled
-		from the UI and a <code>DOMTreeFull</code> class that displays the full DOM tree with all
-		the nodes.</p>
-
-		<p>The controls are called through to to the corresponding iterator function. If you
-		are familiar with  the DOM Level 2 Traversal specification, these controls are
-		fairly easy to understand</p>
-
-		<s3 title="Iterator Group">
-		<ul>
-			<li>Next - calls the <code>next()</code> functions and selects the next node in the tree.</li>
-			<li>Previous - calls the <code>previous()</code> function and selects the previous node in
-     		the tree.</li>
-		</ul>
-		</s3>
-		<s3 title="Selected Node Group">
-     	<ul>
-			<li><code>remove</code> - remove the selected Node and update the DOM tree. You
-    		 must press an iterator button to see next or  previous node selection. </li>
-     		<li><code>add</code> - add a text node, to see the results of adding a node on the iterator.
-     		position. Again you must first press next or previous </li>
-		</ul>
-		</s3>
-		<s3 title="Iterator Settings Group">
-     	<ul>
-			<li><code>createNodeIterator</code> - calls the factory method to create a new iterator 
-   			with the corresponding <code>whatToShow</code> and <code>NameNodeFilter</code> settings.</li>
-				<ul>
-					<li>The root is set to be the root of the document, so it 
-					starts at the top level each time.</li>
-				</ul>
-			 
-			<li><code>whatToShow</code> - you can singly or multiply select values and the 
-			iterator is constrained to showing these types.</li>
-			<li><code>NodeNameFilter</code> - An empty string is converted to null and given 
-			to the <code>NodeNameFilter</code> class.</li>
-				<ul>
-					<li>An empty string matches all nodes.</li>
-					<li>A non-empty string is forced to match node names.</li>
-				</ul>
-			
-		</ul> 
-      </s3>
-    </s2>      
-	<s2 title="Running IteratorView">                           
-<source>java dom.traversal.IteratorView &lt;fileName&gt;</source>
-	</s2>
-</s1>
diff --git a/docs/sam-tree.xml b/docs/sam-tree.xml
deleted file mode 100644
index 94ac0a8..0000000
--- a/docs/sam-tree.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="TreeWalker Sample">
-    <s2 title="TreeWalker">
-        <p>The <code>TreeWalkerviewView</code> is an interactive UI sample that displays the DOM
-        tree. It show the progress of the tree traversal by moving the selection within the
-        DOM tree. Buttons act as a control panel, allowing the user to interactively
-        traverse the tree,  remove nodes, add nodes, and view the results immediately in
-        the tree. </p>
-        <p>The <code>TreeWalkerviewView</code> uses an example filter, 
-		<code>NameNodeFilter</code>, that can be controlled from the UI and a 
-		<code>DOMTreeFull</code> class that displays the full DOM tree
-        with all the nodes.</p>
-        <p>The controls are called through to to the corresponding 
-		<code>TreeWalker</code> function. If you are familiar with the DOM 
-		Level 2 Traversal specification, these controls are
-        fairly easy to understand.</p>
-        <s3 title="Document Order Traversal Group">
-            <ul>
-                <li>Next - calls the <code>next()</code> functions and selects 
-				the next in the tree.</li>
-                <li>Previous - calls the <code>previous()</code> function a and 
-				selects the previous node in the DOM tree.</li>
-            </ul>
-        </s3>
-        <s3 title="Walk Group">
-	        <p>Parent, Previous Sibling, Next Sibling, First Child, Last Child - call the
-	        corresponding function in TreeWalker and show the result as a selected Node.</p>
-        </s3>
-        <s3 title="Selected Node Group">
-            <ul>
-                <li>current - set the current node to the selected node.</li>
-                <li>remove - remove the selected node and update the tree. 
-          		You must press a button to see next or previous node selection.</li>
-                <li>add - add a text node. 
-          		You must press a button to see next or previous node selection.</li>
-            </ul>
-        </s3>
-        <s3 title="Filter Settings Group">
-            <ul>
-                <li><code>createNodeTreeWalker</code> - calls the factory 
-				method to create a new <code>TreeWalker</code> with the 
-				corresponding <code>whatToShow</code> and <code>NodenameFilter</code>
-                settings. The selected node becomes the TreeWalker root.</li>
-                <li><code>whatToShow</code> - you can singly or multiply select 
-				these values by pressing the control key and the 
-				<code>TreeWalker</code> is constrained to these types.</li>
-                <li><code>NodeNameFilter</code> - an empty string is 
-				converted to null and given to the
-                <code>NodeNameFilter</code> example filter class provided.</li>
-                <ul>
-                    <li>An empty string (null) matches ALL nodes.</li>
-                    <li>A non-empty string is forced to match node names.</li>
-                </ul>
-            </ul>
-          </s3>     
-    </s2>                                                    
-    <s2 title="Running TreeWalker">
-<source>java dom.traversal.TreeWalkerView &lt;fileName&gt;</source>
-    </s2>
-</s1>
diff --git a/docs/sam-treeview.xml b/docs/sam-treeview.xml
deleted file mode 100644
index 444f7a1..0000000
--- a/docs/sam-treeview.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="TreeViewer Sample">
-	<s2 title="Running TreeViewer">
-		<p><code>TreeViewer</code> displays the input file in a graphical tree 
-		based interface. This sample highlights the error handling 
-		capabilities of the parser, demonstrating how the parser can 
-		recover from many types of common errors.  </p>
-		<p>Requirements:</p>
-		<ul>
-			<li>&javaparsername; is loaded on your computer.</li>
-			<li>Either:</li>
-			<ul><li>JDK 1.1.8 and Swing1.1.1 are is loaded on your computer.</li></ul>
-			<li>Or:</li>
-			<ul><li>Java 2 (jdk1.2.2)  is loaded on your computer.</li></ul>
-		</ul>
-		<p>Source code: </p>
-		<ul>
-			<li>TreeViewer.java</li>
-			<li>TreeView.java</li>
-			<li>DOMTree.java</li>
-			<li>DefaultImages.java</li>
-		</ul>
-	</s2>
-
-	<s2 title="TreeViewer">
-		<p><em>To run TreeViewer:</em></p>
-		<ol>
-			<li>open up a MS-DOS command line window</li>
-			<li>set the path to the jdk\bin directory</li>
-			<li>change directory to the latest &javaparserdirectory; directory</li>
-			<li>invoke the <code>TreeViewer</code> sample</li>
-		</ol>
-		
-		<p><em>On Windows:</em></p>
-		<p>The easiest way to do this is to create a .bat file using the 
-		Notepad editor. Then <code>TreeViewer</code> can be invoked by double clicking 
-		on the file name or icon. The following command lines assume that 
-		both the jdk and the &javaparserdirectory; directories are located directly below 
-		the c: drive.</p>
-		
-		<p><em>With jdk1.1.8:</em></p>
-<source>set PATH=%PATH%;c:\jdk1.1.8\bin
-set CLASSPATH=%CLASSPATH%;c:\&javaparserdirectory;\xerces.jar;c:\&javaparserdirectory;\xercesSamples.jar
-set CLASSPATH=%CLASSPATH%;c:\Swing-1.1.1\swingall.jar
-cd c:\&javaparserdirectory;
-java ui.TreeViewer data/personal.xml</source>
-		
-		<p><em>With jdk1.2.2:</em></p>
-		<p>Swing is included in the Java 2 release and it doesn't required 
-		a separate reference. </p>
-<source>set PATH=%PATH%;c:\jdk1.2.2\bin
-set CLASSPATH=%CLASSPATH%;c:\&javaparserdirectory;\xerces.jar;c:\&javaparserdirectory;\xercesSamples.jar
-cd c:\&javaparserdirectory;
-java ui.TreeViewer data/personal.xml</source>
-
-		<note>Parse your own XML file instead of data/personal.xml</note>
-	</s2>
-</s1>
diff --git a/docs/samples.xml b/docs/samples.xml
deleted file mode 100644
index 9e97429..0000000
--- a/docs/samples.xml
+++ /dev/null
@@ -1,110 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="Samples">
-	<s2 title="Introduction">
-		<ul>
-			<li><link idref="domcount">DOMCount</link></li>
-			<li><link idref="domcount">SAXCount</link></li>
-			<li><link idref="domwriter">DOMWriter</link></li>
-			<li><link idref="domwriter">SAXWriter</link></li>
-			<li><link idref="domfilter">DOMFilter</link></li>
-			<li><link idref="iterator">IteratorView</link></li>
-			<li><link idref="tree">TreeWalker</link></li>
-			<li><link idref="treeview">TreeViewer</link></li>
-		</ul>
-	</s2>
-	<s2 title="Caveats">
-				<note>&javaparsername;: Running the sample applications 
-		requires that you have already loaded the &javaparsername; software on 
-		your computer.</note>
-		<note>Java: Running the sample applications require that your computer has a 
-		correctly installed JDK. If you do not already have a JDK already on 
-		your computer download one from Sun&apos;s Java website: 
-		<jump href="http://java.sun.com">http://java.sun.com</jump> or from 
-		IBM&apos;s website
-		<jump href="http://www.ibm.com/developer/java/">http://www.ibm.com/developer/java/</jump> 
-		where you can find an &quot;Enhanced Windows JDK&quot; that is optimized 
-		for the Windows platform. The sample applications
-		described in the following pages support Java 1 - JDK 1.1.6. 1.1.7, 1.1.8 or
-		Java 2 - JDK 1.2.2. </note>
-		<note>UNIX: Command lines in the pages linked below use the Windows path
-		separator &apos;;&apos; (semicolon) and directory separator &apos;\&apos; (backslash).. 
-		On UNIX, use the &apos;:&apos; (colon) character to separate the JAR files in the classpath,
-		and replace Windows directory separator &apos;\&apos; (backslash) 
-		with &apos;/&apos; (forward slash).</note>
-	</s2>
-	
-	<s2 title="DOMCount Sample">
-		<p><link idref="domcount">DOMCount</link> parses your input file, 
-		and outputs the total parse time, 
-		along with counts of elements, attributes, text characters, and ignorable 
-		whitespace characters. DOMCount displays errors and 
-		warnings that occur during parsing.</p>
-	</s2>
-	
-	<s2 title="SAXCount Sample">
-		<p><link idref="domcount">SAXCount</link> parses your input file, 
-		and outputs the total parse time, 
-		along with counts of elements, attributes, text characters, and 
-		ignorable whitespace characters. SAXCount displays errors and 
-		warnings that occur during parsing.</p>
-	</s2>
-	
-	<s2 title="DOMWriter Sample">
-		<p><link idref="domwriter">DOMWriter</link> parses a file, and 
-		prints it out in XML format. 
-		The command line option, -c, is used to print files  in 
-		"canonical" XML format, so that two XML documents can be compared. 
-		They also display any errors or warnings that occurred during the 
-		parse.
-		DOMWriter also provides a feature to set the output Java encoding 
-		through the -e switch.</p>
-	</s2>
-	
-	<s2 title="SAXWriter Sample">
-		<p><link idref="domwriter">SAXWriter</link> parses a file, and 
-		prints it out in XML format. The command 
-		line option, -c, is used to print files  in "canonical" XML format, 
-		so that two XML documents can be compared. They also display any 
-		errors or warnings that occurred during the parse.</p>
-	</s2>
-	
-	<s2 title="DOMFilter Sample">
-		<p><link idref="domfilter">DOMFilter</link> shows you how to 
-		search for specific elements in 
-		your XML document.  It uses <code>getElementsByTagName()</code> 
-		to traverse the DOM tree, looking for elements or attributes that 
-		match your specification.</p>
-	</s2>
-		
-	<s2 title="IteratorView Sample">
-		<p><link idref="iterator">IteratorView</link> is an interactive 
-		UI sample that displays the DOM tree. It
-		shows the progress of the iteration by moving the selection within the DOM tree.
-		Buttons act as a control panel, allowing the user to interactively iterate through
-		the tree,  remove nodes, add nodes, and view the results immediately in the tree.</p>
-		<p>The <code>IteratorView</code> uses an example filter, 
-		<code>NameNodeFilter</code>, that can be controlled
-		from the UI and a <code>DOMTreeFull</code> class that displays the full DOM tree with all
-		the nodes.</p>
-	</s2>
-	
-	<s2 title="TreeWalker Sample">
-		<p><link idref="tree">TreeWalkerviewView</link> is an interactive UI sample that displays the DOM
-		tree. It show the progress of the tree traversal by moving the selection within the
-		DOM tree. Buttons act as a control panel, allowing the user to interactively
-		traverse the tree,  remove nodes, add nodes, and view the results immediately in
-		the tree.</p>
-
-		<p>The <code>TreeWalkerviewView</code> uses an example filter, 
-		<code>NameNodeFilter</code>, that can be
-		controlled from the UI and a <code>DOMTreeFull</code> class that 
-		displays the full DOM tree with all the nodes.</p>
-	</s2>
-	
-	<s2 title="Treeviewer Sample">
-		<p><link idref="tree">TreeViewer</link> displays the input XML file in a graphical tree-style 
-		interface.  It will also highlight lines have well-formedness or validation errors.</p>
-	</s2>
-</s1>
diff --git a/docs/schema.xml b/docs/schema.xml
deleted file mode 100644
index 612c4d8..0000000
--- a/docs/schema.xml
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-<s1 title="Schema">
-	<s2 title="Disclaimer">
-		<p>This package contains an implementation of the W3C XML 
-		Schema language. This implementation is experimental. The 
-		<jump href="http://www.w3.org/XML/Group/Schemas.html">XML Schema</jump> 
-		language is still in working draft stage: you 
-		should not consider this implementation complete or correct. 
-		The limitations of this implementation are detailed below. 
-		Please read this document before using this package.</p>
-	</s2>
-	<s2 title="Introduction">
-		<p>This package contains an implementation of a subset of the 
-		W3C XML Schema Language as specified in the 7 April 2000
-        Working Drafts for <jump
-        href="http://www.w3.org/TR/xmlschema-1/">Structures</jump> and
-        <jump
-        href="http://www.w3.org/TR/xmlschema-2/">Datatypes</jump>. The
-        parsers contained in this package are able to read and
-        validate XML documents with the grammar specified in either
-        DTD or XML Schema format.  There is no functionality for
-        accessing typed data.</p> 
-		<p>We are making this package available in order to get 
-		feedback on the features in the XML Schema language 
-		design and on representing an XML document&apos;s grammar 
-		as part of the document&apos;s DOM tree. We intend to update 
-		this package until it implements all of the functionality 
-		of the then current XML Schema Working Draft. If you are 
-		interested in a particular unimplemented feature, we welcome 
-		your feedback on the &javaparsername; mailing list.</p>
-	</s2>
-	<s2 title="Limitations">
-		<p>The XML Schema implementation in this package is a 
-		subset of the features defined in the 7 April 2000 
-		XML Schema Working Drafts.</p>
-	</s2>
-    <s2 title='Components Supported'>
-        <ul>
-            <li>Element declarations</li>
-            <li>Model group definitions: group</li>
-            <li>Model groups: all, choice, sequence</li>
-            <li>Attribute declarations</li>
-            <li>Attribute group definitions</li>
-            <li>Simple type definitions</li>
-            <li>Complex type definitions</li>
-            <li>Wildcards: any</li>
-            <li>Wildcards: anyAttribute</li>
-        </ul>
-    </s2>
-    <s2 title='Components NOT Supported'>
-        <ul>
-            <li>Identity constraints: unique, key, keyref</li>
-            <li>Notation declaration</li>
-            <li>Annotation (ignored)</li>
-        </ul>
-    </s2>
-    <s2 title='Features Supported'>
-        <ul>
-            <li>Type derivation</li>
-            <li>Anonymous types</li>
-            <li>Nested element declaration</li>
-            <li>Separate symbol spaces for elements, types, groups, and
-                attribute groups</li>
-            <li>Equivalency classes</li>
-            <li>Target namespace</li>
-            <li>"xsi:schemaLocation" and "xsl:noNamespacesSchemaLocation"</li>
-            <li>Include</li>
-            <li>Import</li>
-            <li>"xsi:type"</li>
-        </ul>
-    </s2>
-    <s2 title='Features NOT Supported'>
-        <ul>
-            <li>Constraints in Chapter 5</li>
-            <li>Nullable</li>
-            <li>Block</li>
-            <li>Abstract</li>
-        </ul>
-    </s2>
-    <s2 title='Datatypes Supported'>
-        <ul>
-            <li>Built-in simple types (primitive, derived)</li>
-            <li>Simple type derivation (restriction, list)</li>
-            <li>Regular expressions</li>
-            <li>Binary (base64, hex)</li>
-            <li>Constraining facets</li>
-        </ul>
-    </s2>
-    <s2 title='Datatypes NOT Supported'>
-        <ul>
-            <li>Date/time -- ISO8601 (work in progress)</li>
-        </ul>
-    </s2>
-	<s2 title="Other Limitations">
-		<p>The schema is specified by the xsi:schemaLocation or
-		xsi:noNamespaceSchemaLocation attribute on the root 
-		element of the document. The xsi prefix must be bound to the 
-		Schema document instance namespace, as specified by the
-		working draft specification. See the sample provided in the
-		Usage section.</p>
-	</s2>
-	<s2 title="Usage">
-		<p>In this release, schema validation has been integrated with the 
-		regular SAXParser and DOMParser classes. No special classes are 
-		required to parse documents that use a schema.</p>
-		<p>Documents that use XML Schema grammars specify the location of the
-		grammar using an xsi:schemaLocation attribute attached to the root / top-level element 
-		in the document. Here is an example with no target namspace: </p>
-<source>&lt;document
-  xmlns:xsi='http://www.w3.org/1999/XMLSchema-instance'
-  xsi:noNamespaceSchemaLocation='document.xsd'&gt;
-...
-&lt;/document&gt;</source>
-		<p>Here is an example with a target namespace. Note that it is an
-		error to specify a different namespace than the target namespace
-		defined in Schema.</p>
-<source>&lt;document
-  xmlns='NS'
-  xmlns:xsi='http://www.w3.org/1999/XMLSchema-instance' 
-  xsi:schemaLocation='NS document.xsd'&gt;
-...
-&lt;/document&gt;</source>
-		<p>Review the sample file, 'data/personal.xsd' for an example of an XML 
-		Schema grammar.</p>
-	</s2>
-</s1>
diff --git a/docs/site-book.xml b/docs/site-book.xml
deleted file mode 100644
index b7816f7..0000000
--- a/docs/site-book.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE book SYSTEM "./dtd/book.dtd">
-
-<book title="Xerces-J Documentation" copyright="1999, 2000 The Apache Software Foundation">
-  <external href="../index.html"  label="Home"/>
-  
-  <separator/>
-  <document id="index"       label="Readme"       source="xerces-j/readme.xml"      />
-  <document id="install"     label="Installation" source="xerces-j/install.xml"     />
-  <separator/>
-  <document id="api"         label="API Docs"     source="xerces-j/api.xml"         />
-  <document id="samples"     label="Samples"      source="xerces-j/samples.xml"     />
-  <hidden   id="iterator"                         source="xerces-j/sam-iterator.xml"/>
-  <hidden   id="tree"                             source="xerces-j/sam-tree.xml"    />
-  <document id="schema"      label="Schema"       source="xerces-j/schema.xml"      />
-  <separator/>
-  <document id="properties"  label="Properties"   source="xerces-j/properties.xml"  />
-  <document id="features"    label="Features"     source="xerces-j/features.xml"    />
-  <group    id="faqs"        label="FAQs"                                            >
-    <entry  id="faq-general"                      source="xerces-j/faq-general.xml" />
-    <entry  id="faq-build"                        source="xerces-j/faq-build.xml"   />
-    <entry  id="faq-write"                        source="xerces-j/faq-write.xml"   />
-    <entry  id="faq-migrate"                      source="xerces-j/faq-migrate.xml" />
-    <entry  id="faq-common"                       source="xerces-j/faq-common.xml"  />
-  </group>
-  
-  <separator/>
-  <document id="releases"    label="Releases"     source="xerces-j/releases.xml"    />
-  <document id="caveats"     label="Caveats"      source="xerces-j/caveats.xml"     />
-  <document id="feedback"    label="Feedback"     source="xerces-j/feedback.xml"    />
-  <separator/>
-  <document id="y2k"         label="Y2K Compliance" source="xerces-j/y2k.xml"         />
-</book>
diff --git a/docs/y2k.xml b/docs/y2k.xml
deleted file mode 100644
index 93fc8e0..0000000
--- a/docs/y2k.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE s1 SYSTEM "./dtd/document.dtd">
-
-<s1 title="Y2K Compliance">
-	<s2 title="Apache Xerces Parser Year-2000 Readiness">
-		<p>Q: Are the Xerces parsers Year-2000-compliant? </p>
-		<p>Yes, Xerces-J and Xerces-C are Year 2000 compliant. 
-		They do not currently use any dates at all (at least until the XML 
-		Schema date datatypes are fully supported).  However, you may still 
-		have Y2K problems if the underlying OS or Java implementation has 
-		problems with dates past year 2000 (e.g. OS calls which accept or 
-		return year numbers).</p>
-		<p>Most (UNIX) systems store dates internally as signed 32-bit 
-		integers which contain the number of seconds since 1st January 1970, 
-		so the magic boundary to worry about is the year 2038 and not 2000. 
-		But modern operating systems shouldn't cause any trouble at all.</p>
-		
-		<p>The Apache Xerces project is an open-source software product 
-		of the Apache Software Foundation. The project and the Foundation 
-		cannot and does not offer legal assurances regarding any suitability 
-		of the software for your application. There are several commercial 
-		support organizations and derivative products available that may be 
-		able to certify the software and provide you with any assurances you 
-		may require (IBM's Websphere product is one of them).</p> 
-		<p>The Apache HTTP server software is distributed with the following 
-		disclaimer, found in the software license: 	</p>
-<source>THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
-ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.</source>
-	</s2>
-</s1>
diff --git a/proposals/XRI-requirements/issues.dtd b/proposals/XRI-requirements/issues.dtd
deleted file mode 100644
index 67da412..0000000
--- a/proposals/XRI-requirements/issues.dtd
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- edited with XML Spy v3.0 (http://www.xmlspy.com) by Edward Staub (private) -->
-<!--DTD generated by XML Spy v3.0 (http://www.xmlspy.com)-->
-<!ENTITY nbsp "&#160;">
-<!ELEMENT a (strong | em)>
-<!ATTLIST a
-	href CDATA #IMPLIED
-	name CDATA #IMPLIED
->
-<!ELEMENT cat (#PCDATA)>
-<!ELEMENT categories (cat+)>
-<!ELEMENT def (#PCDATA | br | a | ul)*>
-
-<!ELEMENT br EMPTY>
-<!ELEMENT seeAlso EMPTY>
-<!ELEMENT edReqNote (#PCDATA)>
-<!ELEMENT em (#PCDATA | small)*>
-<!ELEMENT li (#PCDATA | a | em | ul)*>
-<!ELEMENT small (#PCDATA)>
-<!ELEMENT strong (#PCDATA)>
-<!ELEMENT ul (li*)>
-<!ELEMENT mailHeaderSet (li+)>
-<!ATTLIST mailHeaderSet
-	id (gen | xdev) #REQUIRED
->
-<!ELEMENT mailHeaderSets (mailHeaderSet+)>
-<!ELEMENT ref (#PCDATA | br)*>
-<!ATTLIST ref
-	set CDATA #REQUIRED
-	id CDATA #REQUIRED
->
-<!ELEMENT refs (ref)*>
-<!ELEMENT voteSet (vote*)>
-<!ATTLIST voteSet
-	opened CDATA #REQUIRED
-	closed CDATA #REQUIRED
-	callForVote CDATA #IMPLIED
->
-<!ELEMENT vote (voteComment?)>
-<!ATTLIST vote
-	voter CDATA #REQUIRED
-	email CDATA #REQUIRED
-	vote CDATA #REQUIRED
->
-<!ELEMENT voteComment (#PCDATA)>
-<!ELEMENT req (def, seeAlso*, edReqNote*, voteSet?, refs)>
-<!ATTLIST req
-	status (approved | tooQuiet | hardnessConflict | vetoConflict | rejected | unevaluated) "unevaluated"
-	id CDATA #REQUIRED
-	strength (hard | soft) #REQUIRED
-	cat CDATA #REQUIRED
->
-<!ATTLIST seeAlso
-	id CDATA #REQUIRED
-	type (Conflict) #IMPLIED
->
-<!ELEMENT requirementCatalog (categories, requirements, mailHeaderSets)>
-<!ATTLIST requirementCatalog
-	date CDATA #REQUIRED
-	version CDATA #REQUIRED
->
-<!ELEMENT requirements (req+)>
diff --git a/proposals/XRI-requirements/issues.html b/proposals/XRI-requirements/issues.html
deleted file mode 100644
index fc35a7a..0000000
--- a/proposals/XRI-requirements/issues.html
+++ /dev/null
@@ -1,2132 +0,0 @@
-<!-- saved from url=(0022)http://internet.e-mail -->
-<html xmlns:fo="http://www.w3.org/1999/XSL/Format">
-<head>
-<title>Proposed Xerces2 Requirements -  4 September 2000</title>
-</head>
-<body bgcolor="#FFFFFF">
-<h1>Proposed Xerces2 Requirements</h1>
-<h4>Date: 4 September 2000<br>
-  Editors: &nbsp;&nbsp;<a href="mailto:estaub@mediaone.net">Ed Staub</a>&nbsp;&nbsp;<a href="mailto:twleung@sauria.com">Ted Leung</a>
-</h4>
-<hr>
-<h2>Schema</h2>
-<p>Proposed requirements are organized into categories. &nbsp;Some requirements 
-  occur in more than one category in the future.</p>
-<p>Each requirement has a number. Underneath the number is a "hardness" 
-  and "status".</p>
-<dl>
-<dt>Possible "hardness" values are:</dt>
-<dd>
-<b>hard</b> - Xerces2 must and shall meet this requirement<br>
-<b>soft</b> - Xerces2 should meet this requirement, but it may be dropped 
-    because of conflicting requirements or time pressures</dd>
-<dt>
-<br>
-    Possible "status" values are:</dt>
-<dd>
-<b>approved</b> - there appears to be a clear consensus<br>
-<b>tooQuiet</b> - there may be a consensus, but there hasn't been enough 
-    input to be sure <br>
-<b>hardnessConflict</b> - there is conflict over whether this is a hard or 
-    soft requirement<b>
-<br>
-    vetoConflict</b> - there is a conflict over whether this proposed requirement 
-    is a requirement at all<br>
-<b>rejected</b> - the proposed requirement appears to be dead<br>
-<b>unevaluated</b> - editor hasn't finished reviewing input
-					</dd>
-</dl>
-<hr>
-<h2>Requirements by Number</h2>
-<a href="#req.1">1</a>
-			&nbsp;	&nbsp;
-			The code shall be maintainable and simple to read.<br>
-<a href="#req.2">2</a>
-			&nbsp;	&nbsp;
-			The parser should have a competitive memory footprint (competitive
-against the other Java based parsers out there).
-<br>
-<a href="#req.3">3</a>
-			&nbsp;	&nbsp;
-			The parser shall be designed so as to allow deployment of minimal subsets suitable for low-end, memory-constrained appli...<br>
-<a href="#req.4">4</a>
-			&nbsp;	&nbsp;
-			The parser shall run well on all virutal machines and 			shall not be optimized toward a particular virtual machine.<br>
-<a href="#req.5">5</a>
-			&nbsp;	&nbsp;
-			Optimizations that interfere with readability,        modularity, or size should be shunned.  <br>
-<br>
-<a href="#req.6">6</a>
-			&nbsp;	&nbsp;
-			The parser should have the smallest possible distribution (JAR) size.<br>
-<a href="#req.7">7</a>
-			&nbsp;	&nbsp;
-			The design of the parser should be documented, with diagrams where they are more expressive than text.<br>
-<a href="#req.8">8</a>
-			&nbsp;	&nbsp;
-			The parser should have the characteristics needed for it to be included in the JDK.<br>
-<a href="#req.9">9</a>
-			&nbsp;	&nbsp;
-			The parser should be upwardly compatible with Xerces.<br>
-<a href="#req.10">10</a>
-			&nbsp;	&nbsp;
-			The parser shall be cleanly modular.<br>
-<br>
-<a href="#req.11">11</a>
-			&nbsp;	&nbsp;
-			Development should be coordinated with xerces-c.<br>
-<a href="#req.12">12</a>
-			&nbsp;	&nbsp;
-			The parser shall support SAX2.<br>
-<a href="#req.13a">13a</a>
-			&nbsp;	&nbsp;
-			
-				Read-only, memory conservative, high performance DOM subset. In some  ways, this is optional, since the alternative...<br>
-<a href="#req.13b">13b</a>
-			&nbsp;	&nbsp;
-			
-				parse-next function, with added control over buffer size.  <br>
-<a href="#req.13c">13c</a>
-			&nbsp;	&nbsp;
-			
-				Some sort of way to tell if a SAX char buffer is going to be  overwritten, so data doesn't have to be copied until ...<br>
-<a href="#req.13d">13d</a>
-			&nbsp;	&nbsp;
-			
-				Serialization support, as is currently in Assaf's classes.  <br>
-<a href="#req.13e">13e</a>
-			&nbsp;	&nbsp;
-			
-				Schema data-type support, which will be needed for XSLT2, and Xalan 2.0  extensions. <br>
-<a href="#req.13f">13f</a>
-			&nbsp;	&nbsp;
-			
-				Small core footprint for standalone, compiled stylesheet capability, for  use on small devices. This would need to ...<br>
-<a href="#req.14">14</a>
-			&nbsp;	&nbsp;
-			The parser shall validate XML 1.0.<br>
-<a href="#req.15">15</a>
-			&nbsp;	&nbsp;
-			 The parser shall support namespaces.<br>
-<br>
-<a href="#req.16">16</a>
-			&nbsp;	&nbsp;
-			 The parser shall support DOM Level 2. <br>
-<a href="#req.18">18</a>
-			&nbsp;	&nbsp;
-			 The parser shall support XML Schema. <br>
-<a href="#req.19">19</a>
-			&nbsp;	&nbsp;
-			 The parser shall support XPath. <br>
-<a href="#req.20">20</a>
-			&nbsp;	&nbsp;
-			 The parser should support XInclude. <br>
-<br>
-<a href="#req.21">21</a>
-			&nbsp;	&nbsp;
-			 The parser should support write validation of a DOM tree or revalidation. <br>
-<a href="#req.22">22</a>
-			&nbsp;	&nbsp;
-			 The parser shall support grammar access for both DTD and Schema. <br>
-<a href="#req.23">23</a>
-			&nbsp;	&nbsp;
-			 No significant speed penalty should be invoked for unused features, notably validation. When not validating, the parser...<br>
-<a href="#req.24">24</a>
-			&nbsp;	&nbsp;
-			 The parser should provide best-of-breed performance across all JIT's (not just Hotspot). Such performance
-shall not com...<br>
-<a href="#req.25">25</a>
-			&nbsp;	&nbsp;
-			 The parser should support grammar caching and precompilation. <br>
-<br>
-<a href="#req.28">28</a>
-			&nbsp;	&nbsp;
-			 Xerces Native API.  The parser should provide a reasonable core API (fast!) upon which to layer other API's.  Examples ...<br>
-<a href="#req.29">29</a>
-			&nbsp;	&nbsp;
-			 The project should produce testcases for both conformance and benchmarking.  <br>
-<a href="#req.30">30</a>
-			&nbsp;	&nbsp;
-			 The parse shall support SAX 1 <br>
-<br>
-<a href="#req.31">31</a>
-			&nbsp;	&nbsp;
-			 The core parser should not directly support any tree model. <br>
-<a href="#req.32">32</a>
-			&nbsp;	&nbsp;
-			 The parser shall support Java 1.1 <br>
-<a href="#req.33">33</a>
-			&nbsp;	&nbsp;
-			 The parser should support loading and validating only certainrequested portions of a document -- a useful feature  when...<br>
-<a href="#req.34">34</a>
-			&nbsp;	&nbsp;
-			 The parser shall support the XML  Information Set. <br>
-<a href="#req.35">35</a>
-			&nbsp;	&nbsp;
-			 The parser should support pull model parsing. <br>
-<br>
-<a href="#req.37">37</a>
-			&nbsp;	&nbsp;
-			 The DOM should emit events to interested listeners when changes are made to the DOM <br>
-<a href="#req.38">38</a>
-			&nbsp;	&nbsp;
-			 The parser should support 
-					RELAX
-				. <br>
-<a href="#req.39">39</a>
-			&nbsp;	&nbsp;
-			 The parser should allow for automatic detection of compressed/encrypted documents. <br>
-<hr>
-<h2>Requirement Categories</h2>
-<a href="#cat.{.}">Architecture</a>
-<br>
-<a href="#cat.{.}">Standards</a>
-<br>
-<a href="#cat.{.}">Features</a>
-<br>
-<a href="#cat.{.}">Memory</a>
-<br>
-<a href="#cat.{.}">Speed</a>
-<br>
-<a href="#cat.{.}">Quality</a>
-<br>
-<a href="#cat.{.}">Other</a>
-<br>
-<hr>
-<h2>Requirements by Category</h2>
-<h3>
-<a name="#cat.{.}"></a>Architecture</h3>
-<table border="1" width="95%">
-<tr>
-<td valign="top">
-<p>
-<a name="req.3"></a><b>3.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;approved</p>
-</td><td valign="top">
-<p>
-<b>
-<def>The parser shall be designed so as to allow deployment of minimal subsets suitable for low-end, memory-constrained applications
-			<br>The build process shall create both:
-<ul>
-					<li>a .jar file containing all standard components of Xerces (xerces.jar).</li>
-					<li>a set of .jar files which together contain everything in xerces.jar, broken into the following components:
-<ul>
-							<li>xerces kernel, which supports the “internal APIs” and SAX support</li>
-							<li>DOM support</li>
-							<li>Validation support</li>
-							<li>other components of large size which can be easily factored and for which there is a significant audience who will benefit from not including them in a deployment.</li>
-						</ul>
-					</li>
-				</ul>
-			</def>
-</b>
-</p>
-<blockquote>
-<p>
-			See also:
-		<a href="#req.2">2</a>
-		&nbsp;&nbsp;
-	
-			See also:
-		<a href="#req.13">13</a>
-		&nbsp;&nbsp;
-	</p>
-<b><i>Voted</i></b>
-		 on from 26-Aug-00 to 4-Sept-00.  Votes:
-	<ul>
-<li>
-<a href="mailto:CurtA@techie.com">Curt Arnold</a>
-			: +1<blockquote>
-<voteComment>If this type of surgery is possible, then it should help
-requirement 2 since loading unused classes could be avoided.
-</voteComment>
-</blockquote>
-</li>
-<li>
-<a href="mailto:chris.laprun@nist.gov">Chris Laprun</a>
-			: +1</li>
-<li>
-<a href="mailto:twleung@sauria.com">Ted Leung</a>
-			: +1</li>
-<li>
-<a href="mailto:duncan@x180.com">James Duncan Davidson</a>
-			: +1</li>
-<li>
-<a href="mailto:mhk@dia.dk">Mikael Helbo Kjaer</a>
-			: +1</li>
-</ul>
-<b><i>References</i></b>
-<br>
-<p>"<ref set="gen" id="2091">It should be possible to build a parser as a set of Jar files        so that a smaller parser can be assembled which fits the need of a        particular implementation. For example, in TV sets do you really need        validation?</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2091.html">
-					<strong>[spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2091">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Sat Jul         08 2000 - 07:31:16 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2223">Where I am now we use XML as a wire format, so the data volume is small,  and parsing takes place on the client (the customer's e-commerce  environment) and on the server. Small footprint (memory *and* disk)  are much more important in this context than speed or even validation.  </ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2223.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2223">
-					<em>Rod McChesney</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000         - 01:32:31 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2223">... many applications could benefit ...</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2223.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2223">
-					<em>Rod McChesney</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000         - 01:32:31 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="xdev" id="1324">"small-but-performant-ambitious"  devices vs. "as-small-and-cheap-as-possible" devices</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1324.html">
-					<strong>RE: REDOM Design discussion.</strong>
-				</a>
-				<a name="1324">
-					<em>Paulo Gaspar <small>(Sat Jul 15 2000 - 15:33:49         MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-<p>"<ref set="xdev" id="1361">I [am] a proponent [of support for] "small-but-perfrormant-ambitious", not  "as-small-and-cheap-as-possible" [devices] </ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1361.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1361">
-					<em>James Duncan Davidson <small>(Tue Jul 18 2000 -         00:28:02 MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-</table>
-<h3>
-<a name="#cat.{.}"></a>Standards</h3>
-<table border="1" width="95%">
-<tr>
-<td valign="top">
-<p>
-<a name="req.12"></a><b>12.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;approved</p>
-</td><td valign="top">
-<p>
-<b>
-<def>The parser shall support SAX2.</def>
-</b>
-</p>
-<blockquote>
-<p>
-			See also:
-		<a href="#req.13">13</a>
-		&nbsp;&nbsp;
-	</p>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2203.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2203">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         23:42:10 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2243.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2243">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:49:04         MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.14"></a><b>14.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;approved</p>
-</td><td valign="top">
-<p>
-<b>
-<def>The parser shall validate XML 1.0.</def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2243.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2243">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:49:04         MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.15"></a><b>15.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;approved</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser shall support namespaces.</def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2243.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2243">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:49:04         MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.18"></a><b>18.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;approved</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser shall support XML Schema. </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2242.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2242">
-					<em>Eric         Ye</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:48:42 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2243.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2243">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:49:04         MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.19"></a><b>19.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;approved</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser shall support XPath. </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2245.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2245">
-					<em>Donald         Ball</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:57:59         MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2275.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2275">
-					<em>Brett         McLaughlin</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 16:07:32         MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2284.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2284">
-					<em>Eduardo         Pelegri--Llopart</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         19:31:22 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2285.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2285">
-					<em>Jeffrey         Rodriguez</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 19:38:42         MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2320.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2320">
-					<em>Stefano         Mazzocchi</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 - 01:11:58         MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1277.html">
-					<strong>Re: XRI requirements</strong>
-				</a>
-				<a name="1277">
-					<em>Jeffrey Rodriguez <small>(Wed Jul 12 2000 - 09:59:50         MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.20"></a><b>20.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser should support XInclude. </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>"<ref set="gen" id="2245">+1</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2245.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2245">
-					<em>Donald         Ball</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:57:59         MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2271">+1</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2271.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2271">
-					<em>Stefano         Mazzocchi</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 15:02:47         MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2285">+1</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2285.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2285">
-					<em>Jeffrey         Rodriguez</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 19:38:42         MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.22"></a><b>22.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser shall support grammar access for both DTD and Schema. </def>
-</b>
-</p>
-<blockquote>
-<p>
-			See also:
-		<a href="#req.13">13</a>
-		&nbsp;&nbsp;
-	</p>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2242.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2242">
-					<em>Eric         Ye</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:48:42 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.30"></a><b>30.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;rejected</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parse shall support SAX 1 </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>"<ref set="gen" id="2249">-1</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2249.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2249">
-					<em>Brett         McLaughlin</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 03:07:59         MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2257">-1</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2257.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2257">
-					<em>N. Sean         Timm</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 05:59:47         MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2271">-1</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2271.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2271">
-					<em>Stefano         Mazzocchi</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 15:02:47         MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.32"></a><b>32.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;rejected</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser shall support Java 1.1 </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>"<ref set="gen" id="2249">-1</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2249.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2249">
-					<em>Brett         McLaughlin</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 03:07:59         MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2257">-1</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2257.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2257">
-					<em>N. Sean         Timm</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 05:59:47         MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2271">-1</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2271.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2271">
-					<em>Stefano         Mazzocchi</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 15:02:47         MEST)</em>
-			</li>
-</p>
-<p>"<ref set="xdev" id="1314">+1</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1314.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1314">
-					<em>Jeffrey Rodriguez <small>(Fri Jul 14 2000 -         18:47:28 MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-<p>"<ref set="xdev" id="1317">+-0</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1317.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1317">
-					<em>James Duncan Davidson <small>(Fri Jul 14 2000 -         19:22:19 MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.34"></a><b>34.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser shall support the XML  Information Set. </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>"<ref set="gen" id="2298">+1</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2298.html">
-					<strong>Re: [Xerces2] Requirements list; 'Xerces2'?;         cross-posting</strong>
-				</a>&nbsp;<a name="2298">
-					<em>Arnaud         Le Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 20:46:38         MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2321">+1</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2321.html">
-					<strong>Re: [Xerces2] Requirements list; 'Xerces2'?;         cross-posting</strong>
-				</a>&nbsp;<a name="2321">
-					<em>Stefano         Mazzocchi</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 - 01:13:00         MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-</table>
-<h3>
-<a name="#cat.{.}"></a>Features</h3>
-<table border="1" width="95%">
-<tr>
-<td valign="top">
-<p>
-<a name="req.13a"></a><b>13a.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def>
-				<br>Read-only, memory conservative, high performance DOM subset. In some  ways, this is optional, since the alternative is that the XSLT processor  implement it's own DOM, as it does today. But it would be neat and simpler  if only one DOM implementation needed to exist.  <br>  a) Document-order indexes or API as a DOM extension. I know of few or  no conformant XSLT processors that can do without this.  <br>  b) [optional] isWhite() method as a DOM extensions (pure telling of  whether or not the text contains non-whitespace), for performance reasons.  <br>  c) Some sort of weak reference, where nodes could be released if not  referenced, and then rebuilt if requested. For performance and memory  footprint.  </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2203.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2203">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         23:42:10 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2296.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2296">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         19:59:46 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.13b"></a><b>13b.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def>
-				<br>parse-next function, with added control over buffer size.  </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2203.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2203">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         23:42:10 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2296.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2296">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         19:59:46 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.13c"></a><b>13c.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def>
-				<br>Some sort of way to tell if a SAX char buffer is going to be  overwritten, so data doesn't have to be copied until this occurs.  </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2203.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2203">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         23:42:10 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2296.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2296">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         19:59:46 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.13d"></a><b>13d.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def>
-				<br>Serialization support, as is currently in Assaf's classes.  </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2203.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2203">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         23:42:10 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2296.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2296">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         19:59:46 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.13e"></a><b>13e.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def>
-				<br>Schema data-type support, which will be needed for XSLT2, and Xalan 2.0  extensions. </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2203.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2203">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         23:42:10 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2296.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2296">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         19:59:46 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.13f"></a><b>13f.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def>
-				<br>Small core footprint for standalone, compiled stylesheet capability, for  use on small devices. This would need to include the Serializer. I'm not  sure if this should really be a separate micro-parser?   </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2203.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2203">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         23:42:10 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2296.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2296">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         19:59:46 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.16"></a><b>16.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;approved</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser shall support DOM Level 2. </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2243.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2243">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:49:04         MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.21"></a><b>21.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser should support write validation of a DOM tree or revalidation. </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2242.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2242">
-					<em>Eric         Ye</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:48:42 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.28"></a><b>28.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> Xerces Native API.  The parser should provide a reasonable core API (fast!) upon which to layer other API's.  Examples of such API's include SAX2, DOM, and JDOM. </def>
-</b>
-</p>
-<blockquote>
-<p>
-			See also:
-		<a href="#req.10">10</a>
-		&nbsp;&nbsp;
-	</p>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2207.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2207">
-					<em>Brett         McLaughlin</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 00:28:32         MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2221">JDOM is an important up and coming API that already has established a large and rapidly growing groundswell of support and in the  developer community.</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2221.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2221">
-					<em>James         Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         01:15:59 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.31"></a><b>31.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The core parser should not directly support any tree model. </def>
-</b>
-</p>
-<blockquote>
-<p>
-			See also:
-		<a href="#req.10">10</a>
-		&nbsp;&nbsp;
-	</p>
-<b><i>References</i></b>
-<br>
-<p>"<ref set="gen" id="2154">My understanding of the design, which I think is good, is that the  "core" actually doesn't directly support any tree model.  <br>                API Layer JDOM DOM SAX2  <br>               Core Layer Java parser code </ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2154.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2154">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 03:41:05 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2263.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2263">
-					<em>Jason         Hunter</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 07:51:22         MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2326.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2326">
-					<em>Tim         Bray</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 - 02:33:14         MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1169.html">
-					<strong>[spinnaker] Design discussion</strong>
-				</a>
-				<a name="1169">
-					<em>James Duncan Davidson <small>(Mon Jul 10 2000 -         08:04:29 MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1179.html">
-					<strong>Re: [spinnaker] Design discussion</strong>
-				</a>
-				<a name="1179">
-					<em>costin@eng.sun.com <small>(Mon Jul 10 2000         - 20:40:06 MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1185.html">
-					<strong>Re: [spinnaker] Design discussion</strong>
-				</a>
-				<a name="1185">
-					<em>Edwin Goei <small>(Tue Jul 11 2000 -         00:48:20 MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1211.html">
-					<strong>Re: ?? Design discussion - xerces-design-dev new         list</strong>
-				</a>
-				<a name="1211">
-					<em>Arnaud Le Hors <small>         (Tue Jul 11 2000 - 06:51:24 MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1320.html">
-					<strong>[Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1320">
-					<em>Ed Staub <small>(Fri Jul 14 2000 - 23:34:45         MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1321.html">
-					<strong>Re: [Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1321">
-					<em>Brett McLaughlin <small>(Fri Jul 14 2000 -         23:52:26 MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1322.html">
-					<strong>Re: [Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1322">
-					<em>Arved Sandstrom <small>(Sat Jul 15 2000 -         01:08:07 MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.33"></a><b>33.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser should support loading and validating only certainrequested portions of a document -- a useful feature  when dealing with large xml databases, for example.   See the W3C <a href="http://www.w3.org/TR/WD-xml-fragment">
-					<em>XML Fragement Interchange</em>
-				</a> Working Draft. </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2276.html">
-					<strong>RE: XRI requirements</strong>
-				</a>&nbsp;<a name="2276">
-					<em>James Snell</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         07:25:50 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.35"></a><b>35.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser should support pull model parsing. </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2310.html">
-					<strong>Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2310">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul         12 2000 - 21:46:16 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2323.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2323">
-					<em>Ted Leung</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 -         02:08:55 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2333.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2333">
-					<em>Ted Leung</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 -         06:46:09 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2335.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2335">
-					<em>Eric Hodges</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 -         09:15:49 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2340.html">
-					<strong>RE: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2340">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Thu Jul         13 2000 - 06:29:25 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.37"></a><b>37.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The DOM should emit events to interested listeners when changes are made to the DOM </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1201.html">
-					<strong>Re: ?? Design discussion - xerces-design-dev new         list</strong>
-				</a>
-				<a name="1201">
-					<em>Kelly Campbell <small>         (Tue Jul 11 2000 - 03:08:57 MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.38"></a><b>38.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser should support <a href="http://www.xml.gr.jp/relax/">
-					<em>RELAX</em>
-				</a>. </def>
-</b>
-</p>
-<blockquote>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.39"></a><b>39.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser should allow for automatic detection of compressed/encrypted documents. </def>
-</b>
-</p>
-<blockquote>
-</blockquote>
-</td>
-</tr>
-</table>
-<h3>
-<a name="#cat.{.}"></a>Memory</h3>
-<table border="1" width="95%">
-<tr>
-<td valign="top">
-<p>
-<a name="req.2"></a><b>2.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;approved</p>
-</td><td valign="top">
-<p>
-<b>
-<def>The parser should have a competitive memory footprint (competitive
-against the other Java based parsers out there).
-</def>
-</b>
-</p>
-<blockquote>
-<p>
-			See also:
-		<a href="#req.3">3</a>
-		&nbsp;&nbsp;
-	</p>
-<b><i>Voted</i></b>
-		 on from 26-Aug-00 to 4-Sept-00.  Votes:
-	<ul>
-<li>
-<a href="mailto:CurtA@techie.com">Curt Arnold</a>
-			: +1<blockquote>
-<voteComment>I assume that the comparison would be some basket of scenarios, so
-that being efficient with large documents could offset a slightly
-greater initial load size.</voteComment>
-</blockquote>
-</li>
-<li>
-<a href="mailto:chris.laprun@nist.gov">Chris Laprun</a>
-			: +1</li>
-<li>
-<a href="mailto:twleung@sauria.com">Ted Leung</a>
-			: +1</li>
-<li>
-<a href="mailto:duncan@x180.com">James Duncan Davidson</a>
-			: +1</li>
-<li>
-<a href="mailto:mhk@dia.dk">Mikael Helbo Kjaer</a>
-			: +1</li>
-</ul>
-<b><i>References</i></b>
-<br>
-<p>"<ref set="gen" id="2091">This means small distribution size (JAR file)        and small memory footprint.</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2091.html">
-					<strong>[spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2091">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Sat Jul         08 2000 - 07:31:16 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2203.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2203">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         23:42:10 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2341.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2341">
-					<em>Stefano Mazzocchi</em>
-				</a>&nbsp;<em>(Thu Jul 13         2000 - 01:52:43 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2345.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2345">
-					<em>costin@eng.sun.com</em>
-				</a>&nbsp;<em>(Thu Jul 13         2000 - 21:46:20 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.6"></a><b>6.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;rejected</p>
-</td><td valign="top">
-<p>
-<b>
-<def>The parser should have the smallest possible distribution (JAR) size.</def>
-</b>
-</p>
-<blockquote>
-<p>
-			See also:
-		<a href="#req.3">3</a>
-		&nbsp;&nbsp;
-	</p>
-<b><i>Voted</i></b>
-		 on from 26-Aug-00 to 4-Sept-00.  Votes:
-	<ul>
-<li>
-<a href="mailto:CurtA@techie.com">Curt Arnold</a>
-			: +1 to remove</li>
-<li>
-<a href="mailto:chris.laprun@nist.gov">Chris Laprun</a>
-			: +1 to remove</li>
-<li>
-<a href="mailto:twleung@sauria.com">Ted Leung</a>
-			: +1 to remove</li>
-<li>
-<a href="mailto:duncan@x180.com">James Duncan Davidson</a>
-			: +1 to remove</li>
-<li>
-<a href="mailto:mhk@dia.dk">Mikael Helbo Kjaer</a>
-			: +1 to remove</li>
-</ul>
-<blockquote>
-<i>Ed:</i>The votes below were votes to remove this requirement.  Its concerns are addressed elsewhere.</blockquote>
-<b><i>References</i></b>
-<br>
-<p>"<ref set="gen" id="2091">This means small distribution size (JAR file)        and small memory footprint.  </ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2091.html">
-					<strong>[spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2091">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Sat Jul         08 2000 - 07:31:16 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2093">These two requirements [small memory footprint, small jar size -ed] are in direct conflict.   </ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2093.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2093">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Sat Jul 08         2000 - 19:56:58 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-</table>
-<h3>
-<a name="#cat.{.}"></a>Speed</h3>
-<table border="1" width="95%">
-<tr>
-<td valign="top">
-<p>
-<a name="req.4"></a><b>4.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;approved</p>
-</td><td valign="top">
-<p>
-<b>
-<def>The parser shall run well on all virutal machines and 			shall not be optimized toward a particular virtual machine.</def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2091.html">
-					<strong>[spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2091">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Sat Jul         08 2000 - 07:31:16 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1299.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1299">
-					<em>Jim Driscoll <small>(Thu Jul 13 2000 - 18:12:19         MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1307.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1307">
-					<em>James Duncan Davidson <small>(Fri Jul 14 2000 -         06:38:44 MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.23"></a><b>23.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> No significant speed penalty should be invoked for unused features, notably validation. When not validating, the parser should run almost as fast as a non-validating parser. </def>
-</b>
-</p>
-<blockquote>
-<p>
-			See also:
-		<a href="#req.10">10</a>
-		&nbsp;&nbsp;
-	</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.24"></a><b>24.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser should provide best-of-breed performance across all JIT's (not just Hotspot). Such performance
-shall not come at the expense of requirement 5.</def>
-</b>
-</p>
-<blockquote>
-<p>
-			See also:
-		<a href="#req.5">5</a>
-		&nbsp;&nbsp;
-	</p>
-<b><i>References</i></b>
-<br>
-<p>"<ref set="xdev" id="1317">-1 (on JDK 1.1)</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1317.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1317">
-					<em>James Duncan Davidson <small>(Fri Jul 14 2000 -         19:22:19 MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-<p>"<ref set="xdev" id="1323">Fast enough to not notice that a parse happened for most data (10 lines to  10K).  To expand on that, when I have Ant read it's data from build.xml, I  shouldn't notice. If I send a bit of form encoded XML data to a server, and  then get some back, it shouldn't be appreciable considering the connection  cost. </ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1323.html">
-					<strong>Re: [Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1323">
-					<em>James Duncan Davidson <small>(Sat Jul 15 2000 -         06:31:24 MEST)</small>
-					</em>
-				</a>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.25"></a><b>25.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The parser should support grammar caching and precompilation. </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2242.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2242">
-					<em>Eric         Ye</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:48:42 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2261.html">
-					<strong>Re: XRI requirements</strong>
-				</a>&nbsp;<a name="2261">
-					<em>Jeffrey Rodriguez</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 07:01:23 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-</table>
-<h3>
-<a name="#cat.{.}"></a>Quality</h3>
-<table border="1" width="95%">
-<tr>
-<td valign="top">
-<p>
-<a name="req.1"></a><b>1.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;approved</p>
-</td><td valign="top">
-<p>
-<b>
-<def>The code shall be maintainable and simple to read.</def>
-</b>
-</p>
-<blockquote>
-<p>
-			See also:
-		<a href="#req.5">5</a>
-		&nbsp;&nbsp;
-	</p>
-<b><i>Voted</i></b>
-		 on from 26-Aug-00 to 4-Sept-00.  Votes:
-	<ul>
-<li>
-<a href="mailto:CurtA@techie.com">Curt Arnold</a>
-			: +1<blockquote>
-<voteComment>+1 on intent.  But how can this be a "shall" when there is not a measure
-for maintainability or simplicity.  Are there specific criteria that we
-want to establish such as the Sun's Java coding conventions or something
-else from the Apache world?
-</voteComment>
-</blockquote>
-</li>
-<li>
-<a href="mailto:chris.laprun@nist.gov">Chris Laprun</a>
-			: +1</li>
-<li>
-<a href="mailto:twleung@sauria.com">Ted Leung</a>
-			: +1</li>
-<li>
-<a href="mailto:duncan@x180.com">James Duncan Davidson</a>
-			: +1<blockquote>
-<voteComment>I have an easy way to measure this.. Committers should only be committers if
-they are prepared to read the code commits. If the code commit isn't
-readable to somebody and they throw a flag, then it probably fails the test.
-For example, my criteria on such code would be that I can understand it. If
-everybody's criteria is this, then it works.
-</voteComment>
-</blockquote>
-</li>
-<li>
-<a href="mailto:mhk@dia.dk">Mikael Helbo Kjaer</a>
-			: +1</li>
-</ul>
-<b><i>References</i></b>
-<br>
-<p>"<ref set="gen" id="2091"> Above all, this is the primary goal        for any openly developed project as without the ability to read the        code, it's impossible for people to contribute and get involved.</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2091.html">
-					<strong>[spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2091">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Sat Jul         08 2000 - 07:31:16 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2138.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2138">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000 -         23:18:54 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2186">[current code too complex, scares off users]</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2186.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2186">
-					<em>Brett McLaughlin</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 22:17:03 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2209">I don't think I am [willing to trade off some performance for clearly written code]. Performance is too damned important in the XML  world</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2209.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2209">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul         12 2000 - 00:25:18 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2220">You're not going to get a diverse developer community built around code that  is too damned hard to read... </ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2220.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2220">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul         12 2000 - 01:11:58 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2311.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2311">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul         12 2000 - 23:44:52 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.5"></a><b>5.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;approved</p>
-</td><td valign="top">
-<p>
-<b>
-<def>Optimizations that interfere with readability,        modularity, or size should be shunned.  </def>
-</b>
-</p>
-<blockquote>
-<p>
-			See also:
-		<a href="#req.1">1</a>
-		&nbsp;&nbsp;
-	</p>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2091.html">
-					<strong>[spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2091">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Sat Jul         08 2000 - 07:31:16 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.7"></a><b>7.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;approved</p>
-</td><td valign="top">
-<p>
-<b>
-<def>The design of the parser should be documented, with diagrams where they are more expressive than text.</def>
-</b>
-</p>
-<blockquote>
-<b><i>Voted</i></b>
-		 on from 26-Aug-00 to 4-Sept-00.  Votes:
-	<ul>
-<li>
-<a href="mailto:CurtA@techie.com">Curt Arnold</a>
-			: +0</li>
-<li>
-<a href="mailto:chris.laprun@nist.gov">Chris Laprun</a>
-			: +1</li>
-<li>
-<a href="mailto:twleung@sauria.com">Ted Leung</a>
-			: +1</li>
-<li>
-<a href="mailto:duncan@x180.com">James Duncan Davidson</a>
-			: +1</li>
-<li>
-<a href="mailto:mhk@dia.dk">Mikael Helbo Kjaer</a>
-			: +1</li>
-</ul>
-<b><i>References</i></b>
-<br>
-<p>"<ref set="gen" id="2104">... would benefit greatly from requirements and design documentation; most especially some diagrams. I find that a dozen or so good diagrams often do a better job of  conveying the design and, perhaps more importantly, the design approach or  philosophy, than written documents.  </ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2104.html">
-					<strong>design docs and diagrams [was Re: [spinnaker]         Announce]</strong>
-				</a>&nbsp;<a name="2104">
-					<em>Randall J.         Parr</em>
-				</a>&nbsp;<em>(Sun Jul 09 2000 - 18:43:49         MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.9"></a><b>9.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def>The parser should be upwardly compatible with Xerces.</def>
-</b>
-</p>
-<blockquote>
-<blockquote>
-<i>Ed:</i>This needs refinement.</blockquote>
-<b><i>References</i></b>
-<br>
-<p>"<ref set="gen" id="2110">Whatever happened to making things upgrade compatiable. </ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2110.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2110">
-					<em>MITCHELL SOJDEHEI</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 02:57:49 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.10"></a><b>10.</b>
-<br>
-        &nbsp;&nbsp;hard<br>
-        &nbsp;&nbsp;approved</p>
-</td><td valign="top">
-<p>
-<b>
-<def>The parser shall be cleanly modular.</def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2091.html">
-					<strong>[spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2091">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Sat Jul         08 2000 - 07:31:16 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2122.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2122">
-					<em>costin@eng.sun.com</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 19:54:06 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2130.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2130">
-					<em>costin@eng.sun.com</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 22:48:38 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2154">[star vs. pipeline]</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2154.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2154">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 03:41:05 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-</table>
-<h3>
-<a name="#cat.{.}"></a>Other</h3>
-<table border="1" width="95%">
-<tr>
-<td valign="top">
-<p>
-<a name="req.8"></a><b>8.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def>The parser should have the characteristics needed for it to be included in the JDK.</def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2108.html">
-					<strong>[spinnaker] XML Hack Article</strong>
-				</a>&nbsp;<a name="2108">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>         (Mon Jul 10 2000 - 00:47:01 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.11"></a><b>11.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def>Development should be coordinated with xerces-c.</def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>"<ref set="gen" id="2133">I'd also like to see this be coordinated with the xerces-c developers ... it would be  nice to keep the two parsers in sync so that changes to one parser and  relatively easy to implement in the other. 		 </ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2133.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2133">
-					<em>Joe Polastre</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000         - 23:05:18 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2144">I disagree...</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2144.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2144">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 23:34:54 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2161">Java is a very different language from C++, and you need  different strategies.  </ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2161.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2161">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 05:25:51 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2182">...there's much to be gained by keeping the  overall architecture and design the same between the two versions. </ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2182.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2182">
-					<em>Andy Heninger</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000         - 18:59:24 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2194">[forcing deep similarity is bad]</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2194.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2194">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 22:39:19 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2222">...trying to find one design that fits both  languages well will produce one design that doesn't quite fit either  language. </ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2222.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2222">
-					<em>Eric Hodges</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         01:23:23 MEST)</em>
-			</li>
-</p>
-<p>"<ref set="gen" id="2241">Let's push for high-level designs that  can accommodate any OO language...</ref>"<br>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2241.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2241">
-					<em>Arved Sandstrom</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 02:22:53 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2246.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2246">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul         12 2000 - 02:55:07 MEST)</em>
-			</li>
-</p>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2248.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2248">
-					<em>Eric Hodges</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         03:03:32 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-<tr>
-<td valign="top">
-<p>
-<a name="req.29"></a><b>29.</b>
-<br>
-        &nbsp;&nbsp;soft<br>
-        &nbsp;&nbsp;unevaluated</p>
-</td><td valign="top">
-<p>
-<b>
-<def> The project should produce testcases for both conformance and benchmarking.  </def>
-</b>
-</p>
-<blockquote>
-<b><i>References</i></b>
-<br>
-<p>
-<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2242.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2242">
-					<em>Eric         Ye</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:48:42 MEST)</em>
-			</li>
-</p>
-</blockquote>
-</td>
-</tr>
-</table>
-</body>
-</html>
diff --git a/proposals/XRI-requirements/issues.xml b/proposals/XRI-requirements/issues.xml
deleted file mode 100644
index 71a2665..0000000
--- a/proposals/XRI-requirements/issues.xml
+++ /dev/null
@@ -1,4316 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- edited with XML Spy v3.0 (http://www.xmlspy.com) by Edward Staub (private) -->
-<?xml-stylesheet type="text/xsl" href="issues.xsl"?>
-<!DOCTYPE requirementCatalog SYSTEM "issues.dtd">
-<requirementCatalog date="4 September 2000" version="1.5">
-	<!-- Checked apache general list through messages 2091 through 2375 -->
-	<!-- Checked apache xerces-j-dev list messages 1160 through 1380 -->
-	<categories>
-		<cat>Architecture</cat>
-		<cat>Standards</cat>
-		<cat>Features</cat>
-		<cat>Memory</cat>
-		<cat>Speed</cat>
-		<cat>Quality</cat>
-		<cat>Other</cat>
-	</categories>
-	<requirements>
-		<req id="1" status="approved" strength="hard" cat="Quality">
-			<def>The code shall be maintainable and simple to read.</def>
-			<seeAlso id="5"/>
-			<voteSet opened="26-Aug-00" closed="4-Sept-00">
-				<vote voter="Curt Arnold" email="CurtA@techie.com" vote="+1">
-					<voteComment>+1 on intent.  But how can this be a "shall" when there is not a measure
-for maintainability or simplicity.  Are there specific criteria that we
-want to establish such as the Sun's Java coding conventions or something
-else from the Apache world?
-</voteComment>
-				</vote>
-				<vote voter="Chris Laprun" email="chris.laprun@nist.gov" vote="+1"/>
-				<vote voter="Ted Leung" email="twleung@sauria.com" vote="+1"/>
-				<vote voter="James Duncan Davidson" email="duncan@x180.com" vote="+1">
-					<voteComment>I have an easy way to measure this.. Committers should only be committers if
-they are prepared to read the code commits. If the code commit isn't
-readable to somebody and they throw a flag, then it probably fails the test.
-For example, my criteria on such code would be that I can understand it. If
-everybody's criteria is this, then it works.
-</voteComment>
-				</vote>
-				<vote voter="Mikael Helbo Kjaer" email="mhk@dia.dk" vote="+1"/>
-			</voteSet>
-			<refs>
-				<ref set="gen" id="2091"> Above all, this is the primary goal        for any openly developed project as without the ability to read the        code, it's impossible for people to contribute and get involved.</ref>
-				<ref set="gen" id="2138"/>
-				<ref set="gen" id="2186">[current code too complex, scares off users]</ref>
-				<ref set="gen" id="2209">I don't think I am [willing to trade off some performance for clearly written code]. Performance is too damned important in the XML  world</ref>
-				<ref set="gen" id="2220">You're not going to get a diverse developer community built around code that  is too damned hard to read... </ref>
-				<ref set="gen" id="2311"/>
-			</refs>
-		</req>
-		<req id="2" status="approved" strength="soft" cat="Memory">
-			<def>The parser should have a competitive memory footprint (competitive
-against the other Java based parsers out there).
-</def>
-			<seeAlso id="3"/>
-			<voteSet opened="26-Aug-00" closed="4-Sept-00">
-				<vote voter="Curt Arnold" email="CurtA@techie.com" vote="+1">
-					<voteComment>I assume that the comparison would be some basket of scenarios, so
-that being efficient with large documents could offset a slightly
-greater initial load size.</voteComment>
-				</vote>
-				<vote voter="Chris Laprun" email="chris.laprun@nist.gov" vote="+1"/>
-				<vote voter="Ted Leung" email="twleung@sauria.com" vote="+1"/>
-				<vote voter="James Duncan Davidson" email="duncan@x180.com" vote="+1"/>
-				<vote voter="Mikael Helbo Kjaer" email="mhk@dia.dk" vote="+1"/>
-			</voteSet>
-			<refs>
-				<ref set="gen" id="2091">This means small distribution size (JAR file)        and small memory footprint.</ref>
-				<ref set="gen" id="2203"/>
-				<ref set="gen" id="2341"/>
-				<ref set="gen" id="2345"/>
-			</refs>
-		</req>
-		<req id="3" status="approved" strength="hard" cat="Architecture">
-			<def>The parser shall be designed so as to allow deployment of minimal subsets suitable for low-end, memory-constrained applications
-			<br/>The build process shall create both:
-<ul>
-					<li>a .jar file containing all standard components of Xerces (xerces.jar).</li>
-					<li>a set of .jar files which together contain everything in xerces.jar, broken into the following components:
-<ul>
-							<li>xerces kernel, which supports the “internal APIs” and SAX support</li>
-							<li>DOM support</li>
-							<li>Validation support</li>
-							<li>other components of large size which can be easily factored and for which there is a significant audience who will benefit from not including them in a deployment.</li>
-						</ul>
-					</li>
-				</ul>
-			</def>
-			<seeAlso id="2"/>
-			<seeAlso id="13"/>
-			<voteSet opened="26-Aug-00" closed="4-Sept-00">
-				<vote voter="Curt Arnold" email="CurtA@techie.com" vote="+1">
-					<voteComment>If this type of surgery is possible, then it should help
-requirement 2 since loading unused classes could be avoided.
-</voteComment>
-				</vote>
-				<vote voter="Chris Laprun" email="chris.laprun@nist.gov" vote="+1"/>
-				<vote voter="Ted Leung" email="twleung@sauria.com" vote="+1"/>
-				<vote voter="James Duncan Davidson" email="duncan@x180.com" vote="+1"/>
-				<vote voter="Mikael Helbo Kjaer" email="mhk@dia.dk" vote="+1"/>
-			</voteSet>
-			<refs>
-				<ref set="gen" id="2091">It should be possible to build a parser as a set of Jar files        so that a smaller parser can be assembled which fits the need of a        particular implementation. For example, in TV sets do you really need        validation?</ref>
-				<ref set="gen" id="2223">Where I am now we use XML as a wire format, so the data volume is small,  and parsing takes place on the client (the customer's e-commerce  environment) and on the server. Small footprint (memory *and* disk)  are much more important in this context than speed or even validation.  </ref>
-				<ref set="gen" id="2223">... many applications could benefit ...</ref>
-				<ref set="xdev" id="1324">"small-but-performant-ambitious"  devices vs. "as-small-and-cheap-as-possible" devices</ref>
-				<ref set="xdev" id="1361">I [am] a proponent [of support for] "small-but-perfrormant-ambitious", not  "as-small-and-cheap-as-possible" [devices] </ref>
-			</refs>
-		</req>
-		<req id="4" status="approved" strength="hard" cat="Speed">
-			<def>The parser shall run well on all virutal machines and 			shall not be optimized toward a particular virtual machine.</def>
-			<refs>
-				<ref set="gen" id="2091"/>
-				<ref set="xdev" id="1299"/>
-				<ref set="xdev" id="1307"/>
-			</refs>
-		</req>
-		<req id="5" status="approved" strength="soft" cat="Quality">
-			<def>Optimizations that interfere with readability,        modularity, or size should be shunned.  </def>
-			<seeAlso id="1"/>
-			<refs>
-				<ref set="gen" id="2091"/>
-			</refs>
-		</req>
-				<req id="6" status="rejected" strength="soft" cat="Memory">
-			<def>The parser should have the smallest possible distribution (JAR) size.</def>
-			<seeAlso id="3"/>
-			<edReqNote>The votes below were votes to remove this requirement.  Its concerns are addressed elsewhere.</edReqNote>
-			<voteSet opened="26-Aug-00" closed="4-Sept-00">
-				<vote voter="Curt Arnold" email="CurtA@techie.com" vote="+1 to remove"/>
-				<vote voter="Chris Laprun" email="chris.laprun@nist.gov" vote="+1 to remove"/>
-				<vote voter="Ted Leung" email="twleung@sauria.com" vote="+1 to remove"/>
-				<vote voter="James Duncan Davidson" email="duncan@x180.com" vote="+1 to remove"/>
-				<vote voter="Mikael Helbo Kjaer" email="mhk@dia.dk" vote="+1 to remove"/>
-			</voteSet>
-			<refs>
-				<ref set="gen" id="2091">This means small distribution size (JAR file)        and small memory footprint.  </ref>
-				<ref set="gen" id="2093">These two requirements [small memory footprint, small jar size -ed] are in direct conflict.   </ref>
-			</refs>
-		</req>
-
-		<req id="7" status="approved" strength="soft" cat="Quality">
-			<def>The design of the parser should be documented, with diagrams where they are more expressive than text.</def>
-			<voteSet opened="26-Aug-00" closed="4-Sept-00">
-				<vote voter="Curt Arnold" email="CurtA@techie.com" vote="+0"/>
-				<vote voter="Chris Laprun" email="chris.laprun@nist.gov" vote="+1"/>
-				<vote voter="Ted Leung" email="twleung@sauria.com" vote="+1"/>
-				<vote voter="James Duncan Davidson" email="duncan@x180.com" vote="+1"/>
-				<vote voter="Mikael Helbo Kjaer" email="mhk@dia.dk" vote="+1"/>
-			</voteSet>
-			<refs>
-				<ref set="gen" id="2104">... would benefit greatly from requirements and design documentation; most especially some diagrams. I find that a dozen or so good diagrams often do a better job of  conveying the design and, perhaps more importantly, the design approach or  philosophy, than written documents.  </ref>
-			</refs>
-		</req>
-		<req id="8" strength="soft" cat="Other">
-			<def>The parser should have the characteristics needed for it to be included in the JDK.</def>
-			<refs>
-				<ref set="gen" id="2108"/>
-			</refs>
-		</req>
-		<req id="9" strength="soft" cat="Quality">
-			<def>The parser should be upwardly compatible with Xerces.</def>
-			<edReqNote>This needs refinement.</edReqNote>
-			<refs>
-				<ref set="gen" id="2110">Whatever happened to making things upgrade compatiable. </ref>
-			</refs>
-		</req>
-		<req id="10" status="approved" strength="hard" cat="Quality">
-			<def>The parser shall be cleanly modular.</def>
-			<refs>
-				<ref set="gen" id="2091"/>
-				<ref set="gen" id="2122"/>
-				<ref set="gen" id="2130"/>
-				<ref set="gen" id="2154">[star vs. pipeline]</ref>
-			</refs>
-		</req>
-		<req id="11" strength="soft" cat="Other">
-			<def>Development should be coordinated with xerces-c.</def>
-			<refs>
-				<ref set="gen" id="2133">I'd also like to see this be coordinated with the xerces-c developers ... it would be  nice to keep the two parsers in sync so that changes to one parser and  relatively easy to implement in the other. 		 </ref>
-				<ref set="gen" id="2144">I disagree...</ref>
-				<ref set="gen" id="2161">Java is a very different language from C++, and you need  different strategies.  </ref>
-				<ref set="gen" id="2182">...there's much to be gained by keeping the  overall architecture and design the same between the two versions. </ref>
-				<ref set="gen" id="2194">[forcing deep similarity is bad]</ref>
-				<ref set="gen" id="2222">...trying to find one design that fits both  languages well will produce one design that doesn't quite fit either  language. </ref>
-				<ref set="gen" id="2241">Let's push for high-level designs that  can accommodate any OO language...</ref>
-				<ref set="gen" id="2246"/>
-				<ref set="gen" id="2248"/>
-			</refs>
-		</req>
-		<req id="12" status="approved" strength="hard" cat="Standards">
-			<def>The parser shall support SAX2.</def>
-			<seeAlso id="13"/>
-			<refs>
-				<ref set="gen" id="2203"/>
-				<ref set="gen" id="2243"/>
-			</refs>
-		</req>
-		<req id="13a" strength="soft" cat="Features">
-			<def>
-				<br/>Read-only, memory conservative, high performance DOM subset. In some  ways, this is optional, since the alternative is that the XSLT processor  implement it's own DOM, as it does today. But it would be neat and simpler  if only one DOM implementation needed to exist.  <br/>  a) Document-order indexes or API as a DOM extension. I know of few or  no conformant XSLT processors that can do without this.  <br/>  b) [optional] isWhite() method as a DOM extensions (pure telling of  whether or not the text contains non-whitespace), for performance reasons.  <br/>  c) Some sort of weak reference, where nodes could be released if not  referenced, and then rebuilt if requested. For performance and memory  footprint.  </def>
-			<refs>
-				<ref set="gen" id="2203"/>
-				<ref set="gen" id="2296"/>
-			</refs>
-		</req>
-		<req id="13b" strength="soft" cat="Features">
-			<def>
-				<br/>parse-next function, with added control over buffer size.  </def>
-			<refs>
-				<ref set="gen" id="2203"/>
-				<ref set="gen" id="2296"/>
-			</refs>
-		</req>
-		<req id="13c" strength="soft" cat="Features">
-			<def>
-				<br/>Some sort of way to tell if a SAX char buffer is going to be  overwritten, so data doesn't have to be copied until this occurs.  </def>
-			<refs>
-				<ref set="gen" id="2203"/>
-				<ref set="gen" id="2296"/>
-			</refs>
-		</req>
-		<req id="13d" strength="soft" cat="Features">
-			<def>
-				<br/>Serialization support, as is currently in Assaf's classes.  </def>
-			<refs>
-				<ref set="gen" id="2203"/>
-				<ref set="gen" id="2296"/>
-			</refs>
-		</req>
-		<req id="13e" strength="soft" cat="Features">
-			<def>
-				<br/>Schema data-type support, which will be needed for XSLT2, and Xalan 2.0  extensions. </def>
-			<refs>
-				<ref set="gen" id="2203"/>
-				<ref set="gen" id="2296"/>
-			</refs>
-		</req>
-		<req id="13f" strength="soft" cat="Features">
-			<def>
-				<br/>Small core footprint for standalone, compiled stylesheet capability, for  use on small devices. This would need to include the Serializer. I'm not  sure if this should really be a separate micro-parser?   </def>
-			<refs>
-				<ref set="gen" id="2203"/>
-				<ref set="gen" id="2296"/>
-			</refs>
-		</req>
-		<req id="14" status="approved" strength="hard" cat="Standards">
-			<def>The parser shall validate XML 1.0.</def>
-			<refs>
-				<ref set="gen" id="2243"/>
-			</refs>
-		</req>
-		<req id="15" status="approved" strength="hard" cat="Standards">
-			<def> The parser shall support namespaces.</def>
-			<refs>
-				<ref set="gen" id="2243"/>
-			</refs>
-		</req>
-		<req id="16" status="approved" strength="hard" cat="Features">
-			<def> The parser shall support DOM Level 2. </def>
-			<refs>
-				<ref set="gen" id="2243"/>
-			</refs>
-		</req>
-		<req id="18" status="approved" strength="hard" cat="Standards">
-			<def> The parser shall support XML Schema. </def>
-			<refs>
-				<ref set="gen" id="2242"/>
-				<ref set="gen" id="2243"/>
-			</refs>
-		</req>
-		<req id="19" status="approved" strength="hard" cat="Standards">
-			<def> The parser shall support XPath. </def>
-			<refs>
-				<ref set="gen" id="2245"/>
-				<ref set="gen" id="2275"/>
-				<ref set="gen" id="2284"/>
-				<ref set="gen" id="2285"/>
-				<ref set="gen" id="2320"/>
-				<ref set="xdev" id="1277"/>
-			</refs>
-		</req>
-		<req id="20" strength="soft" cat="Standards">
-			<def> The parser should support XInclude. </def>
-			<refs>
-				<ref set="gen" id="2245">+1</ref>
-				<ref set="gen" id="2271">+1</ref>
-				<ref set="gen" id="2285">+1</ref>
-			</refs>
-		</req>
-		<req id="21" strength="soft" cat="Features">
-			<def> The parser should support write validation of a DOM tree or revalidation. </def>
-			<refs>
-				<ref set="gen" id="2242"/>
-			</refs>
-		</req>
-		<req id="22" strength="hard" cat="Standards">
-			<def> The parser shall support grammar access for both DTD and Schema. </def>
-			<seeAlso id="13"/>
-			<refs>
-				<ref set="gen" id="2242"/>
-			</refs>
-		</req>
-		<req id="23" strength="soft" cat="Speed">
-			<def> No significant speed penalty should be invoked for unused features, notably validation. When not validating, the parser should run almost as fast as a non-validating parser. </def>
-			<seeAlso id="10"/>
-			<refs/>
-		</req>
-		<req id="24" strength="soft" cat="Speed">
-			<def> The parser should provide best-of-breed performance across all JIT's (not just Hotspot). Such performance
-shall not come at the expense of requirement 5.</def>
-			<seeAlso id="5"/>
-			<refs>
-				<ref set="xdev" id="1317">-1 (on JDK 1.1)</ref>
-				<ref set="xdev" id="1323">Fast enough to not notice that a parse happened for most data (10 lines to  10K).  To expand on that, when I have Ant read it's data from build.xml, I  shouldn't notice. If I send a bit of form encoded XML data to a server, and  then get some back, it shouldn't be appreciable considering the connection  cost. </ref>
-			</refs>
-		</req>
-		<req id="25" strength="soft" cat="Speed">
-			<def> The parser should support grammar caching and precompilation. </def>
-			<refs>
-				<ref set="gen" id="2242"/>
-				<ref set="gen" id="2261"/>
-			</refs>
-		</req>
-		<!--		<req id="27" strength="soft" cat="Speed"> 			<def> The parser should provide mid to upper range validation performance across all JVMs. </def> 			<refs> 				<ref set="gen" id="2242"/> 			</refs> 		</req> -->
-		<req id="28" strength="soft" cat="Features">
-			<def> Xerces Native API.  The parser should provide a reasonable core API (fast!) upon which to layer other API's.  Examples of such API's include SAX2, DOM, and JDOM. </def>
-			<seeAlso id="10"/>
-			<refs>
-				<ref set="gen" id="2207"/>
-				<ref set="gen" id="2221">JDOM is an important up and coming API that already has established a large and rapidly growing groundswell of support and in the  developer community.</ref>
-			</refs>
-		</req>
-		<req id="29" strength="soft" cat="Other">
-			<def> The project should produce testcases for both conformance and benchmarking.  </def>
-			<refs>
-				<ref set="gen" id="2242"/>
-			</refs>
-		</req>
-		<req id="30" status="rejected" strength="hard" cat="Standards">
-			<def> The parse shall support SAX 1 </def>
-			<refs>
-				<ref set="gen" id="2249">-1</ref>
-				<ref set="gen" id="2257">-1</ref>
-				<ref set="gen" id="2271">-1</ref>
-			</refs>
-		</req>
-		<req id="31" strength="soft" cat="Features">
-			<def> The core parser should not directly support any tree model. </def>
-			<seeAlso id="10"/>
-			<refs>
-				<ref set="gen" id="2154">My understanding of the design, which I think is good, is that the  "core" actually doesn't directly support any tree model.  <br/>                API Layer JDOM DOM SAX2  <br/>               Core Layer Java parser code </ref>
-				<ref set="gen" id="2263"/>
-				<ref set="gen" id="2326"/>
-				<ref set="xdev" id="1169"/>
-				<ref set="xdev" id="1179"/>
-				<ref set="xdev" id="1185"/>
-				<ref set="xdev" id="1211"/>
-				<ref set="xdev" id="1320"/>
-				<ref set="xdev" id="1321"/>
-				<ref set="xdev" id="1322"/>
-			</refs>
-		</req>
-		<req id="32" status="rejected" strength="hard" cat="Standards">
-			<def> The parser shall support Java 1.1 </def>
-			<refs>
-				<ref set="gen" id="2249">-1</ref>
-				<ref set="gen" id="2257">-1</ref>
-				<ref set="gen" id="2271">-1</ref>
-				<ref set="xdev" id="1314">+1</ref>
-				<ref set="xdev" id="1317">+-0</ref>
-			</refs>
-		</req>
-		<req id="33" strength="soft" cat="Features">
-			<def> The parser should support loading and validating only certainrequested portions of a document -- a useful feature  when dealing with large xml databases, for example.   See the W3C <a href="http://www.w3.org/TR/WD-xml-fragment">
-					<em>XML Fragement Interchange</em>
-				</a> Working Draft. </def>
-			<refs>
-				<ref set="gen" id="2276"/>
-			</refs>
-		</req>
-		<req id="34" strength="hard" cat="Standards">
-			<def> The parser shall support the XML  Information Set. </def>
-			<refs>
-				<ref set="gen" id="2298">+1</ref>
-				<ref set="gen" id="2321">+1</ref>
-			</refs>
-		</req>
-		<req id="35" strength="soft" cat="Features">
-			<def> The parser should support pull model parsing. </def>
-			<refs>
-				<ref set="gen" id="2310"/>
-				<ref set="gen" id="2323"/>
-				<ref set="gen" id="2333"/>
-				<ref set="gen" id="2335"/>
-				<ref set="gen" id="2340"/>
-			</refs>
-		</req>
-		<req id="37" strength="soft" cat="Features">
-			<def> The DOM should emit events to interested listeners when changes are made to the DOM </def>
-			<refs>
-				<ref set="xdev" id="1201"/>
-			</refs>
-		</req>
-		<req id="38" strength="soft" cat="Features">
-			<def> The parser should support <a href="http://www.xml.gr.jp/relax/">
-					<em>RELAX</em>
-				</a>. </def>
-			<refs/>
-		</req>
-		<req id="39" strength="soft" cat="Features">
-			<def> The parser should allow for automatic detection of compressed/encrypted documents. </def>
-			<refs/>
-		</req>
-	</requirements>
-	<mailHeaderSets>
-		<mailHeaderSet id="xdev">
-			<!-- xml-archive-xerces-j-dev -->
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1160.html">
-					<strong>[spinnaker] Announce</strong>
-				</a>
-				<a name="1160">
-					<em>James Duncan Davidson <small>(Sat Jul 08 2000 -         07:31:16 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1164.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1164">
-					<em>Andy Clark <small>(Sat Jul 08 2000 - 09:22:28         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1165.html">
-					<strong>RE: Duplicate Element Declaration         errors</strong>
-				</a>
-				<a name="1165">
-					<em>Andrew Fawcett         <small>(Sat Jul 08 2000 - 13:31:42 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1166.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1166">
-					<em>James Duncan Davidson <small>(Sun Jul 09 2000 -         07:46:31 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1167.html">
-					<strong>RE: Nodes from External Entities are read         only</strong>
-				</a>
-				<a name="1167">
-					<em>Brett Knights <small>         (Sun Jul 09 2000 - 20:52:10 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1168.html">
-					<strong>BUG: SAXParser endElement reports incorrect local         name w/ namespaces</strong>
-				</a>
-				<a name="1168">
-					<em>Kevin         Wiggen <small>(Mon Jul 10 2000 - 05:57:32         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1169.html">
-					<strong>[spinnaker] Design discussion</strong>
-				</a>
-				<a name="1169">
-					<em>James Duncan Davidson <small>(Mon Jul 10 2000 -         08:04:29 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1170.html">
-					<strong>RE: Re[2]: Shema: problem with definition recursive         data types</strong>
-				</a>
-				<a name="1170">
-					<em>Jean-Louis Vila         <small>(Mon Jul 10 2000 - 09:28:36 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1171.html">
-					<strong>RE: complexType derivation by extension &amp;         simpleType</strong>
-				</a>
-				<a name="1171">
-					<em>Jean-Louis Vila         <small>(Mon Jul 10 2000 - 09:38:40 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1172.html">
-					<strong>Bug in DeclHandler</strong>
-				</a>
-				<a name="1172">
-					<em>         Philippe MOUAWAD <small>(Mon Jul 10 2000 - 11:23:32         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1173.html">
-					<strong>Null in the Elements and Attribute</strong>
-				</a>
-				<a name="1173">
-					<em>Khan Intakhab <small>(Mon Jul 10 2000 -         12:22:09 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1174.html">
-					<strong>URGENT: Validation in DOM Parser doesn't         work!</strong>
-				</a>
-				<a name="1174">
-					<em>Martijn Lindhout         <small>(Mon Jul 10 2000 - 13:15:59 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1175.html">
-					<strong>serialize.XMLSerializer little patch</strong>
-				</a>
-				<a name="1175">
-					<em>Frank Taffelt <small>(Mon Jul 10 2000 -         13:38:26 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1176.html">
-					<strong>Urgent: Any one can check it?</strong>
-				</a>
-				<a name="1176">
-					<em>Khan Intakhab <small>(Mon Jul 10 2000 - 14:35:13         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1177.html">
-					<strong>Re: Urgent: Any one can check it?</strong>
-				</a>
-				<a name="1177">
-					<em>Jeffrey Rodriguez <small>(Mon Jul 10 2000 -         20:29:48 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1178.html">
-					<strong>Fw: [spinnaker] Announce</strong>
-				</a>
-				<a name="1178">
-					<em>Edwin Goei <small>(Mon Jul 10 2000 - 20:50:56         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1179.html">
-					<strong>Re: [spinnaker] Design discussion</strong>
-				</a>
-				<a name="1179">
-					<em>costin@eng.sun.com <small>(Mon Jul 10 2000         - 20:40:06 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1180.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1180">
-					<em>Rajiv Mordani <small>(Mon Jul 10 2000 - 22:11:48         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1181.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1181">
-					<em>Rajiv Mordani <small>(Mon Jul 10 2000 - 23:11:35         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1182.html">
-					<strong>Re: [spinnaker] Design discussion</strong>
-				</a>
-				<a name="1182">
-					<em>James Duncan Davidson <small>(Mon Jul 10         2000 - 23:20:35 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1183.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1183">
-					<em>James Duncan Davidson <small>(Mon Jul 10 2000 -         23:22:32 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1184.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1184">
-					<em>Edwin Goei <small>(Tue Jul 11 2000 - 00:25:14         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1185.html">
-					<strong>Re: [spinnaker] Design discussion</strong>
-				</a>
-				<a name="1185">
-					<em>Edwin Goei <small>(Tue Jul 11 2000 -         00:48:20 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1186.html">
-					<strong>Re: [spinnaker] Design discussion</strong>
-				</a>
-				<a name="1186">
-					<em>costin@eng.sun.com <small>(Tue Jul 11 2000         - 01:14:54 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1187.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1187">
-					<em>James Duncan Davidson <small>(Tue Jul 11 2000 -         01:22:08 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1188.html">
-					<strong>Re: [spinnaker] Design discussion</strong>
-				</a>
-				<a name="1188">
-					<em>James Duncan Davidson <small>(Tue Jul 11         2000 - 01:23:42 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1189.html">
-					<strong>RE: [spinnaker] Announce</strong>
-				</a>
-				<a name="1189">
-					<em>Timm, Sean <small>(Tue Jul 11 2000 - 01:43:10         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1190.html">
-					<strong>?? Design discussion</strong>
-				</a>
-				<a name="1190">
-					<em>Eric Ye <small>(Tue Jul 11 2000 - 01:47:07         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1191.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1191">
-					<em>James Duncan Davidson <small>(Tue Jul 11 2000 -         01:54:14 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1192.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1192">
-					<em>Edwin Goei <small>(Tue Jul 11 2000 - 01:58:36         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1193.html">
-					<strong>Re: ?? Design discussion</strong>
-				</a>
-				<a name="1193">
-					<em>James Duncan Davidson <small>(Tue Jul 11 2000 -         02:03:04 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1194.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1194">
-					<em>Eric Ye <small>(Tue Jul 11 2000 - 02:09:26         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1195.html">
-					<strong>Re: ?? Design discussion</strong>
-				</a>
-				<a name="1195">
-					<em>Edwin Goei <small>(Tue Jul 11 2000 - 02:10:18         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1196.html">
-					<strong>Re: ?? Design discussion - xerces-design-dev new         list</strong>
-				</a>
-				<a name="1196">
-					<em>Jeffrey Rodriguez         <small>(Tue Jul 11 2000 - 02:24:45 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1197.html">
-					<strong>Re: ?? Design discussion</strong>
-				</a>
-				<a name="1197">
-					<em>costin@eng.sun.com <small>(Tue Jul 11 2000 -         02:30:22 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1198.html">
-					<strong>Re: ?? Design discussion - xerces-design-dev new         list</strong>
-				</a>
-				<a name="1198">
-					<em>costin@eng.sun.com         <small>(Tue Jul 11 2000 - 02:40:19 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1199.html">
-					<strong>Fw: ?? Design discussion</strong>
-				</a>
-				<a name="1199">
-					<em>Eric Ye <small>(Tue Jul 11 2000 - 02:55:44         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1200.html">
-					<strong>RE: [spinnaker] Announce</strong>
-				</a>
-				<a name="1200">
-					<em>Timm, Sean <small>(Tue Jul 11 2000 - 03:00:05         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1201.html">
-					<strong>Re: ?? Design discussion - xerces-design-dev new         list</strong>
-				</a>
-				<a name="1201">
-					<em>Kelly Campbell <small>         (Tue Jul 11 2000 - 03:08:57 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1202.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1202">
-					<em>Eric Ye <small>(Tue Jul 11 2000 - 03:28:57         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1203.html">
-					<strong>Re: ?? Design discussion - xerces-design-dev new         list</strong>
-				</a>
-				<a name="1203">
-					<em>Jeffrey Rodriguez         <small>(Tue Jul 11 2000 - 03:40:35 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1204.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1204">
-					<em>James Duncan Davidson <small>(Tue Jul 11 2000 -         04:39:12 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1205.html">
-					<strong>Re: ?? Design discussion - xerces-design-dev new         list</strong>
-				</a>
-				<a name="1205">
-					<em>James Duncan Davidson         <small>(Tue Jul 11 2000 - 04:43:17 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1206.html">
-					<strong>Re: ?? Design discussion</strong>
-				</a>
-				<a name="1206">
-					<em>Edwin Goei <small>(Tue Jul 11 2000 - 04:45:39         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1207.html">
-					<strong>Re: ?? Design discussion</strong>
-				</a>
-				<a name="1207">
-					<em>James Duncan Davidson <small>(Tue Jul 11 2000 -         04:47:47 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1208.html">
-					<strong>Directory name [was Re: [spinnaker]         Announce]</strong>
-				</a>
-				<a name="1208">
-					<em>Arnaud Le Hors         <small>(Tue Jul 11 2000 - 05:16:40 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1209.html">
-					<strong>RE: [spinnaker] Announce</strong>
-				</a>
-				<a name="1209">
-					<em>Timm, Sean <small>(Tue Jul 11 2000 - 05:07:29         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1210.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1210">
-					<em>Jeffrey Rodriguez <small>(Tue Jul 11 2000 -         06:21:14 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1211.html">
-					<strong>Re: ?? Design discussion - xerces-design-dev new         list</strong>
-				</a>
-				<a name="1211">
-					<em>Arnaud Le Hors <small>         (Tue Jul 11 2000 - 06:51:24 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1212.html">
-					<strong>Re: ?? Design discussion - xerces-design-dev new         list</strong>
-				</a>
-				<a name="1212">
-					<em>Costin Manolache         <small>(Tue Jul 11 2000 - 07:22:17 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1213.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1213">
-					<em>Jeffrey Rodriguez <small>(Tue Jul 11 2000 -         08:04:43 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1214.html">
-					<strong>RE: [spinnaker] Announce</strong>
-				</a>
-				<a name="1214">
-					<em>Rajiv Mordani <small>(Tue Jul 11 2000 - 08:45:58         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1215.html">
-					<strong>Re: ?? Design discussion - xerces-design-dev new         list</strong>
-				</a>
-				<a name="1215">
-					<em>Rajiv Mordani <small>         (Tue Jul 11 2000 - 08:50:42 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1216.html">
-					<strong>RE: ?? Design discussion - xerces-design-dev new         list</strong>
-				</a>
-				<a name="1216">
-					<em>David Waite <small>         (Tue Jul 11 2000 - 09:07:11 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1217.html">
-					<strong>RE: complexType derivation by extension &amp;         simpleType</strong>
-				</a>
-				<a name="1217">
-					<em>Jean-Louis Vila         <small>(Tue Jul 11 2000 - 09:32:50 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1218.html">
-					<strong>Re: ?? Design discussion - xerces-design-dev new         list</strong>
-				</a>
-				<a name="1218">
-					<em>Jeffrey Rodriguez         <small>(Tue Jul 11 2000 - 11:16:14 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1219.html">
-					<strong>REDOM Design discussion.</strong>
-				</a>
-				<a name="1219">
-					<em>Jeffrey Rodriguez <small>(Tue Jul 11 2000 -         11:28:52 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1220.html">
-					<strong>REDOM Design discussion.</strong>
-				</a>
-				<a name="1220">
-					<em>Jeffrey Rodriguez <small>(Tue Jul 11 2000 -         11:28:53 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1221.html">
-					<strong>RE: DOM Design discussion.</strong>
-				</a>
-				<a name="1221">
-					<em>Jeffrey Rodriguez <small>(Tue Jul 11 2000 -         11:33:08 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1222.html">
-					<strong>Re: serialize.XMLSerializer little         patch</strong>
-				</a>
-				<a name="1222">
-					<em>Jeffrey Rodriguez         <small>(Tue Jul 11 2000 - 11:36:27 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1223.html">
-					<strong>Re: Bug in DeclHandler</strong>
-				</a>
-				<a name="1223">
-					<em>Jeffrey Rodriguez <small>(Tue Jul 11 2000 - 12:01:10         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1224.html">
-					<strong>Re: BUG: SAXParser endElement reports incorrect         local name w/ namespaces</strong>
-				</a>
-				<a name="1224">
-					<em>         Jeffrey Rodriguez <small>(Tue Jul 11 2000 - 12:05:22         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1225.html">
-					<strong>How can I read a DTD?</strong>
-				</a>
-				<a name="1225">
-					<em>Sylvain Julliard <small>(Tue Jul 11 2000 - 13:12:27         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1226.html">
-					<strong>Re: How can I read a DTD?</strong>
-				</a>
-				<a name="1226">
-					<em>Philippe MOUAWAD <small>(Tue Jul 11 2000 -         13:46:22 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1227.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1227">
-					<em>Costin Manolache <small>(Tue Jul 11 2000 -         16:46:10 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1228.html">
-					<strong>supported encodings</strong>
-				</a>
-				<a name="1228">
-					<em>maciejka@tiger.com.pl <small>(Fri Aug 11 2000 -         17:04:20 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1229.html">
-					<strong>DTD parsing?</strong>
-				</a>
-				<a name="1229">
-					<em>Javi         Ferro <small>(Tue Jul 11 2000 - 12:58:18         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1230.html">
-					<strong>XMLValidator not found in import</strong>
-				</a>
-				<a name="1230">
-					<em>Michael jamison <small>(Tue Jul 11 2000 -         17:09:45 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1231.html">
-					<strong>Re: XMLValidator not found in import</strong>
-				</a>
-				<a name="1231">
-					<em>Jeffrey Rodriguez <small>(Tue Jul 11         2000 - 17:43:55 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1232.html">
-					<strong>Re: DTD parsing?</strong>
-				</a>
-				<a name="1232">
-					<em>         Jeffrey Rodriguez <small>(Tue Jul 11 2000 - 17:56:40         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1233.html">
-					<strong>Re: supported encodings</strong>
-				</a>
-				<a name="1233">
-					<em>Jeffrey Rodriguez <small>(Tue Jul 11 2000 -         18:01:36 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1234.html">
-					<strong>Re: supported encodings</strong>
-				</a>
-				<a name="1234">
-					<em>Jeffrey Rodriguez <small>(Tue Jul 11 2000 -         17:40:23 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1235.html">
-					<strong>RE: BUG: SAXParser endElement reports incorrect         local name w/ nam espaces</strong>
-				</a>
-				<a name="1235">
-					<em>         Sieger, Nicholas <small>(Tue Jul 11 2000 - 18:06:48         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1236.html">
-					<strong>Re: How can I read a DTD?</strong>
-				</a>
-				<a name="1236">
-					<em>Jeffrey Rodriguez <small>(Tue Jul 11 2000 -         18:14:21 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1237.html">
-					<strong>RE: BUG: SAXParser endElement reports incorrect         local name w/ nam espaces</strong>
-				</a>
-				<a name="1237">
-					<em>         Jeffrey Rodriguez <small>(Tue Jul 11 2000 - 18:25:04         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1238.html">
-					<strong>Re: supported encodings</strong>
-				</a>
-				<a name="1238">
-					<em>maciejka@tiger.com.pl <small>(Fri Aug 11 2000 -         18:41:59 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1239.html">
-					<strong>Bug in getOwnerElement()</strong>
-				</a>
-				<a name="1239">
-					<em>Philippe MOUAWAD <small>(Tue Jul 11 2000 -         17:55:36 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1240.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1240">
-					<em>Eric Ye <small>(Tue Jul 11 2000 - 19:18:14         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1241.html">
-					<strong>Re: complexType derivation by extension &amp;         simpleType</strong>
-				</a>
-				<a name="1241">
-					<em>Eric Ye <small>         (Tue Jul 11 2000 - 19:29:09 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1242.html">
-					<strong>Fw: ?? Design discussion</strong>
-				</a>
-				<a name="1242">
-					<em>Eric Ye <small>(Tue Jul 11 2000 - 20:13:38         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1243.html">
-					<strong>Re: Bug in getOwnerElement()</strong>
-				</a>
-				<a name="1243">
-					<em>Jeffrey Rodriguez <small>(Tue Jul 11 2000 -         20:13:58 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1244.html">
-					<strong>Re: Errata in XHTML 1.0</strong>
-				</a>
-				<a name="1244">
-					<em>Jim Clune <small>(Tue Jul 11 2000 - 20:22:11         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1245.html">
-					<strong>Re: Directory name [was Re: [spinnaker]         Announce]</strong>
-				</a>
-				<a name="1245">
-					<em>Eric Ye <small>         (Tue Jul 11 2000 - 21:08:19 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1246.html">
-					<strong>Problems with EntityResolver</strong>
-				</a>
-				<a name="1246">
-					<em>Scott Greenough <small>(Tue Jul 11 2000 -         21:29:31 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1247.html">
-					<strong>Re: Directory name [was Re: [spinnaker]         Announce]</strong>
-				</a>
-				<a name="1247">
-					<em>Brett McLaughlin         <small>(Tue Jul 11 2000 - 21:40:32 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1248.html">
-					<strong>Re: Directory name [was Re: [spinnaker]         Announce]</strong>
-				</a>
-				<a name="1248">
-					<em>Rajiv Mordani         <small>(Tue Jul 11 2000 - 22:09:26 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1249.html">
-					<strong>Re: ?? Design discussion - xerces-design-dev new         list</strong>
-				</a>
-				<a name="1249">
-					<em>James Duncan Davidson         <small>(Tue Jul 11 2000 - 22:46:17 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1250.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>
-				<a name="1250">
-					<em>James Duncan Davidson <small>(Tue Jul 11 2000 -         22:52:45 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1251.html">
-					<strong>Re: XMLValidator not found in import</strong>
-				</a>
-				<a name="1251">
-					<em>James Duncan Davidson <small>(Tue Jul 11         2000 - 22:51:26 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1252.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1252">
-					<em>James Duncan Davidson <small>(Tue Jul 11 2000 -         22:50:25 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1254.html">
-					<strong>Re: ?? Design discussion</strong>
-				</a>
-				<a name="1254">
-					<em>James Duncan Davidson <small>(Tue Jul 11 2000 -         22:56:00 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1253.html">
-					<strong>Re: Directory name [was Re: [spinnaker]         Announce]</strong>
-				</a>
-				<a name="1253">
-					<em>James Duncan         Davidson <small>(Tue Jul 11 2000 - 22:57:15         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1255.html">
-					<strong>RE: Directory name [was Re: [spinnaker]         Announce]</strong>
-				</a>
-				<a name="1255">
-					<em>Timm, Sean         <small>(Tue Jul 11 2000 - 23:01:16 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1256.html">
-					<strong>Re: What name?</strong>
-				</a>
-				<a name="1256">
-					<em>         Brett McLaughlin <small>(Tue Jul 11 2000 - 23:18:22         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1257.html">
-					<strong>Re: Nodes from External Entities are read         only</strong>
-				</a>
-				<a name="1257">
-					<em>Eric Ye <small>(Tue         Jul 11 2000 - 23:28:15 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1258.html">
-					<strong>Re: What name?</strong>
-				</a>
-				<a name="1258">
-					<em>Eric         Ye <small>(Wed Jul 12 2000 - 00:06:41         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1259.html">
-					<strong>ignore DTD in XML document and provide an DTD at         runtime</strong>
-				</a>
-				<a name="1259">
-					<em>George Tsai <small>         (Wed Jul 12 2000 - 00:05:58 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1260.html">
-					<strong>Re: XMLValidator not found in import</strong>
-				</a>
-				<a name="1260">
-					<em>Jeffrey Rodriguez <small>(Wed Jul 12         2000 - 00:06:51 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1261.html">
-					<strong>Re: What name?</strong>
-				</a>
-				<a name="1261">
-					<em>         Brett McLaughlin <small>(Wed Jul 12 2000 - 00:36:54         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1262.html">
-					<strong>Encoding</strong>
-				</a>
-				<a name="1262">
-					<em>Igor         Seletskiy <small>(Wed Jul 12 2000 - 01:35:45         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1263.html">
-					<strong>Re: What name?</strong>
-				</a>
-				<a name="1263">
-					<em>         Edwin Goei <small>(Wed Jul 12 2000 - 01:20:43         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1264.html">
-					<strong>Re: ?? Design discussion</strong>
-				</a>
-				<a name="1264">
-					<em>Edwin Goei <small>(Wed Jul 12 2000 - 02:11:25         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1265.html">
-					<strong>Re: What name?</strong>
-				</a>
-				<a name="1265">
-					<em>         James Duncan Davidson <small>(Wed Jul 12 2000 - 02:12:54         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1266.html">
-					<strong>RE: ignore DTD in XML document and provide an DTD         at runtime</strong>
-				</a>
-				<a name="1266">
-					<em>Wayne Jenkins         <small>(Wed Jul 12 2000 - 02:24:10 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1267.html">
-					<strong>RE: What name?</strong>
-				</a>
-				<a name="1267">
-					<em>         David Waite <small>(Wed Jul 12 2000 - 02:20:26         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1268.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1268">
-					<em>Edwin Goei <small>(Wed Jul 12 2000 - 02:26:06         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1269.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1269">
-					<em>Costin Manolache <small>(Wed Jul 12 2000 -         02:40:41 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1270.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>
-				<a name="1270">
-					<em>Eric Ye         <small>(Wed Jul 12 2000 - 02:48:42 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1271.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1271">
-					<em>Edwin Goei <small>(Wed Jul 12 2000 - 02:54:06         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1272.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1272">
-					<em>Costin Manolache <small>(Wed Jul 12 2000 -         03:21:00 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1273.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1273">
-					<em>James Duncan Davidson <small>(Wed Jul 12 2000 -         04:06:48 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1274.html">
-					<strong>Re: javax.xml support</strong>
-				</a>
-				<a name="1274">
-					<em>Jeffrey Rodriguez <small>(Wed Jul 12 2000 - 05:59:41         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1275.html">
-					<strong>Re: XRI requirements</strong>
-				</a>
-				<a name="1275">
-					<em>Jeffrey Rodriguez <small>(Wed Jul 12 2000 - 07:01:23         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1276.html">
-					<strong>Re: ignore DTD in XML document and provide an DTD         at runtime</strong>
-				</a>
-				<a name="1276">
-					<em>Lisa Retief         <small>(Wed Jul 12 2000 - 07:48:29 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1277.html">
-					<strong>Re: XRI requirements</strong>
-				</a>
-				<a name="1277">
-					<em>Jeffrey Rodriguez <small>(Wed Jul 12 2000 - 09:59:50         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1278.html">
-					<strong>Processing XML using bytestream input and DOM         output?</strong>
-				</a>
-				<a name="1278">
-					<em>David Gibbs <small>         (Wed Jul 12 2000 - 15:16:35 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1279.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1279">
-					<em>Jay Sachs <small>(Wed Jul 12 2000 - 16:33:25         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1280.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1280">
-					<em>Costin Manolache <small>(Wed Jul 12 2000 -         17:28:51 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1281.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1281">
-					<em>Jay Sachs <small>(Wed Jul 12 2000 - 17:55:08         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1282.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1282">
-					<em>Costin Manolache <small>(Wed Jul 12 2000 -         18:09:45 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1283.html">
-					<strong>[Xerces2] Requirements list; 'Xerces2'?;         cross-posting</strong>
-				</a>
-				<a name="1283">
-					<em>Ed Staub         <small>(Wed Jul 12 2000 - 19:55:52 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1284.html">
-					<strong>Re: XRI requirements - for those whose are         interested in XPath and Schema Identity         constraints</strong>
-				</a>
-				<a name="1284">
-					<em>Eric Ye <small>         (Wed Jul 12 2000 - 20:00:29 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1285.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1285">
-					<em>Kevin Regan <small>(Wed Jul 12 2000 - 20:11:07         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1286.html">
-					<strong>Re: XRI requirements - for those whose are         interested in XPath and Schema Identity         constraints</strong>
-				</a>
-				<a name="1286">
-					<em>         costin@eng.sun.com <small>(Wed Jul 12 2000 - 20:25:29         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1287.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1287">
-					<em>costin@eng.sun.com <small>(Wed Jul 12 2000 -         20:29:42 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1288.html">
-					<strong>Fw: XRI requirements - for those whose are         interested in XPath and SchemaIdentity         constraints</strong>
-				</a>
-				<a name="1288">
-					<em>Eric Ye <small>         (Wed Jul 12 2000 - 23:18:58 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1289.html">
-					<strong>Document question</strong>
-				</a>
-				<a name="1289">
-					<em>         Stuart D Jackson <small>(Wed Jul 12 2000 - 23:18:12         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1290.html">
-					<strong>RE: XRI requirements - for those whose are         interested in XPath an d SchemaIdentity         constraints</strong>
-				</a>
-				<a name="1290">
-					<em>Arnold, Curt         <small>(Wed Jul 12 2000 - 23:39:56 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1291.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1291">
-					<em>Edwin Goei <small>(Thu Jul 13 2000 - 00:16:57         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1292.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1292">
-					<em>Ted Leung <small>(Thu Jul 13 2000 - 02:42:52         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1293.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1293">
-					<em>Ryan Schmidt <small>(Thu Jul 13 2000 - 05:23:13         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1294.html">
-					<strong>Stupid Question (ints,string)</strong>
-				</a>
-				<a name="1294">
-					<em>Ravan Naidoo <small>(Thu Jul 13 2000 - 08:56:24         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1295.html">
-					<strong>Bug in DeclHandler 2</strong>
-				</a>
-				<a name="1295">
-					<em>Philippe MOUAWAD <small>(Thu Jul 13 2000 - 12:29:26         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1296.html">
-					<strong>Re: [spinnaker] Design discussion</strong>
-				</a>
-				<a name="1296">
-					<em>Eric de Haan <small>(Thu Jul 13 2000 -         15:25:21 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1297.html">
-					<strong>Re: How can I read a DTD?</strong>
-				</a>
-				<a name="1297">
-					<em>Eric de Haan <small>(Thu Jul 13 2000 - 16:23:58         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1298.html">
-					<strong>Bug in DocumentImpl.cloneNode?</strong>
-				</a>
-				<a name="1298">
-					<em>Ramkumar Natarajan <small>(Thu Jul 13 2000         - 17:00:58 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1299.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1299">
-					<em>Jim Driscoll <small>(Thu Jul 13 2000 - 18:12:19         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1300.html">
-					<strong>Strings vs. RecylclableStrings vs int (was Re:         REDOM Design discussion.)</strong>
-				</a>
-				<a name="1300">
-					<em>         Jay Sachs <small>(Thu Jul 13 2000 - 18:11:35         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1301.html">
-					<strong>Re: Bug in DocumentImpl.cloneNode?</strong>
-				</a>
-				<a name="1301">
-					<em>Jeffrey Rodriguez <small>(Thu Jul 13 2000 -         18:15:50 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1302.html">
-					<strong>Building XML over a DTD</strong>
-				</a>
-				<a name="1302">
-					<em>drozdik <small>(Thu Jul 13 2000 - 19:46:23         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1303.html">
-					<strong>Re: Stupid Question (ints,string)</strong>
-				</a>
-				<a name="1303">
-					<em>Edwin Goei <small>(Thu Jul 13 2000 -         21:33:26 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1304.html">
-					<strong>xml-xerces/java make docs</strong>
-				</a>
-				<a name="1304">
-					<em>fleur diana dragan <small>(Fri Jul 14 2000 -         00:47:02 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1305.html">
-					<strong>Re: xml-xerces/java make docs</strong>
-				</a>
-				<a name="1305">
-					<em>Eric Ye <small>(Fri Jul 14 2000 - 01:01:42         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1306.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1306">
-					<em>James Duncan Davidson <small>(Fri Jul 14 2000 -         06:38:43 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1307.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1307">
-					<em>James Duncan Davidson <small>(Fri Jul 14 2000 -         06:38:44 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1308.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1308">
-					<em>James Duncan Davidson <small>(Fri Jul 14 2000 -         06:38:44 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1309.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1309">
-					<em>Ted Leung <small>(Fri Jul 14 2000 - 07:38:08         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1310.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1310">
-					<em>Elliotte Rusty Harold <small>(Fri Jul 14 2000 -         15:28:45 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1311.html">
-					<strong>Trying to run the TreeWalkerviewView and         IteratorView samples</strong>
-				</a>
-				<a name="1311">
-					<em>         glassblower <small>(Fri Jul 14 2000 - 16:14:36         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1312.html">
-					<strong>RE: REDOM Design discussion.</strong>
-				</a>
-				<a name="1312">
-					<em>Timm, Sean <small>(Fri Jul 14 2000 - 17:10:45         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1313.html">
-					<strong>entity resolution with schema         validation</strong>
-				</a>
-				<a name="1313">
-					<em>Blankenship,         David <small>(Fri Jul 14 2000 - 18:15:31         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1314.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1314">
-					<em>Jeffrey Rodriguez <small>(Fri Jul 14 2000 -         18:47:28 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1315.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1315">
-					<em>James Duncan Davidson <small>(Fri Jul 14 2000 -         18:58:22 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1316.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1316">
-					<em>James Duncan Davidson <small>(Fri Jul 14 2000 -         19:12:50 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1317.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1317">
-					<em>James Duncan Davidson <small>(Fri Jul 14 2000 -         19:22:19 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1318.html">
-					<strong>Re: Building XML over a DTD</strong>
-				</a>
-				<a name="1318">
-					<em>drozdik <small>(Fri Jul 14 2000 - 21:11:32         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1319.html">
-					<strong>Re: entity resolution with schema         validation</strong>
-				</a>
-				<a name="1319">
-					<em>Eric Ye <small>         (Fri Jul 14 2000 - 21:49:04 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1320.html">
-					<strong>[Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1320">
-					<em>Ed Staub <small>(Fri Jul 14 2000 - 23:34:45         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1321.html">
-					<strong>Re: [Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1321">
-					<em>Brett McLaughlin <small>(Fri Jul 14 2000 -         23:52:26 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1322.html">
-					<strong>Re: [Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1322">
-					<em>Arved Sandstrom <small>(Sat Jul 15 2000 -         01:08:07 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1323.html">
-					<strong>Re: [Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1323">
-					<em>James Duncan Davidson <small>(Sat Jul 15 2000 -         06:31:24 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1324.html">
-					<strong>RE: REDOM Design discussion.</strong>
-				</a>
-				<a name="1324">
-					<em>Paulo Gaspar <small>(Sat Jul 15 2000 - 15:33:49         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1325.html">
-					<strong>RE: REDOM Design discussion.</strong>
-				</a>
-				<a name="1325">
-					<em>Paulo Gaspar <small>(Sat Jul 15 2000 - 15:37:32         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1326.html">
-					<strong>RE: [Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1326">
-					<em>Paulo Gaspar <small>(Sat Jul 15 2000 - 15:41:04         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1328.html">
-					<strong>Re: [Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1328">
-					<em>Ted Leung <small>(Sat Jul 15 2000 - 23:50:01         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1327.html">
-					<strong>Re: [Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1327">
-					<em>Ted Leung <small>(Sat Jul 15 2000 - 23:49:06         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1329.html">
-					<strong>Re: XRI requirements</strong>
-				</a>
-				<a name="1329">
-					<em>Ted Leung <small>(Sun Jul 16 2000 - 00:02:31         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1330.html">
-					<strong>Re: [Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1330">
-					<em>Arved Sandstrom <small>(Sun Jul 16 2000 -         01:00:16 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1331.html">
-					<strong>Re: XRI requirements</strong>
-				</a>
-				<a name="1331">
-					<em>Arved Sandstrom <small>(Sun Jul 16 2000 - 01:21:42         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1332.html">
-					<strong>Away</strong>
-				</a>
-				<a name="1332">
-					<em>Ted Leung         <small>(Sun Jul 16 2000 - 09:04:34 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1333.html">
-					<strong>RE: XRI requirements - and overdefensiveness in         OpenSourceLand...</strong>
-				</a>
-				<a name="1333">
-					<em>Paulo         Gaspar <small>(Sun Jul 16 2000 - 17:56:17         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1334.html">
-					<strong>[XRI] XRI requirements list posted to Apache         website</strong>
-				</a>
-				<a name="1334">
-					<em>Ed Staub <small>         (Sun Jul 16 2000 - 18:08:56 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1335.html">
-					<strong>RE: XRI requirements - and overdefensiveness in         OpenSourceLand...</strong>
-				</a>
-				<a name="1335">
-					<em>Ed Staub         <small>(Sun Jul 16 2000 - 18:42:45 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1336.html">
-					<strong>RE: XRI requirements - and overdefensiveness in         OpenSourceLand...</strong>
-				</a>
-				<a name="1336">
-					<em>Arved         Sandstrom <small>(Sun Jul 16 2000 - 18:31:44         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1337.html">
-					<strong>Re: XRI requirements - and overdefensiveness in         OpenSourceLand...</strong>
-				</a>
-				<a name="1337">
-					<em>N. Sean         Timm <small>(Sun Jul 16 2000 - 18:48:11         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1338.html">
-					<strong>Xerces vs. com.sun.xml</strong>
-				</a>
-				<a name="1338">
-					<em>Magnus ?or Torfason <small>(Sun Jul 16 2000 - 19:12:38         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1339.html">
-					<strong>Re: XRI requirements - and overdefensiveness in         OpenSourceLand...</strong>
-				</a>
-				<a name="1339">
-					<em>Arved         Sandstrom <small>(Sun Jul 16 2000 - 19:18:25         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1340.html">
-					<strong>An extensibility framework for Xerces and its         clients?</strong>
-				</a>
-				<a name="1340">
-					<em>Ed Staub <small>         (Mon Jul 17 2000 - 06:00:25 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1341.html">
-					<strong>RE: XRI requirements - and overdefensiveness in         OpenSourceLand...</strong>
-				</a>
-				<a name="1341">
-					<em>Paulo         Gaspar <small>(Mon Jul 17 2000 - 07:21:27         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1342.html">
-					<strong>RE: An extensibility framework for Xerces and its         clients?</strong>
-				</a>
-				<a name="1342">
-					<em>Paulo Gaspar         <small>(Mon Jul 17 2000 - 07:21:28 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1343.html">
-					<strong>Re: An extensibility framework for Xerces and its         clients?</strong>
-				</a>
-				<a name="1343">
-					<em>Pae Choi <small>         (Sun Jul 16 2000 - 07:45:04 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1344.html">
-					<strong>Re: An extensibility framework for Xerces and its         clients?</strong>
-				</a>
-				<a name="1344">
-					<em>markd@lutris.com         <small>(Mon Jul 17 2000 - 07:47:39 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1345.html">
-					<strong>RE: XRI requirements - and overdefensiveness in         OpenSourceLand...</strong>
-				</a>
-				<a name="1345">
-					<em>Arved         Sandstrom <small>(Mon Jul 17 2000 - 07:50:19         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1346.html">
-					<strong>RE: An extensibility framework for Xerces and its         clients?</strong>
-				</a>
-				<a name="1346">
-					<em>Ed Staub <small>         (Mon Jul 17 2000 - 13:55:29 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1347.html">
-					<strong>Cannot obtain elements from the         DTD(documentTypeImpl Object)</strong>
-				</a>
-				<a name="1347">
-					<em>Grengbondai, Jules C. <small>(Mon Jul 17 2000 -         15:09:39 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1348.html">
-					<strong>RE: An extensibility framework for Xerces and its         clients?</strong>
-				</a>
-				<a name="1348">
-					<em>Ed Staub <small>         (Mon Jul 17 2000 - 16:58:10 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1349.html">
-					<strong>setValidating method</strong>
-				</a>
-				<a name="1349">
-					<em>Martin Fuhrer <small>(Mon Jul 17 2000 - 17:54:04         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1350.html">
-					<strong>parsing problem with:         &lt;URL&gt;..344&amp;CONTEXT=34..&lt;/URL&gt;</strong>
-				</a>
-				<a name="1350">
-					<em>Armin S. A. Roehrl <small>(Mon Jul 17         2000 - 19:59:02 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1351.html">
-					<strong>Re: parsing problem with:         &lt;URL&gt;..344&amp;CONTEXT=34..&lt;/URL&gt;</strong>
-				</a>
-				<a name="1351">
-					<em>Eric Ye <small>(Mon Jul 17 2000 -         20:12:16 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1352.html">
-					<strong>Re: serialize.XMLSerializer little         patch</strong>
-				</a>
-				<a name="1352">
-					<em>Jeffrey Rodriguez         <small>(Mon Jul 17 2000 - 20:13:38 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1353.html">
-					<strong>Re: setValidating method</strong>
-				</a>
-				<a name="1353">
-					<em>Eric Ye <small>(Mon Jul 17 2000 - 20:54:18         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1354.html">
-					<strong>Re: parsing problem with:         &lt;URL&gt;..344&amp;CONTEXT=34..&lt;/URL&gt;</strong>
-				</a>
-				<a name="1354">
-					<em>Ye_Tao@i2.com <small>(Mon Jul 17 2000 -         20:05:18 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1355.html">
-					<strong>RE: Cannot obtain elements from the         DTD(documentTypeImpl Object)</strong>
-				</a>
-				<a name="1355">
-					<em>Grengbondai, Jules C. <small>(Mon Jul 17 2000 -         21:05:36 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1356.html">
-					<strong>Re: [XRI] XRI requirements list posted to Apache         website</strong>
-				</a>
-				<a name="1356">
-					<em>Edwin Goei <small>         (Mon Jul 17 2000 - 21:26:51 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1357.html">
-					<strong>Re: Cannot obtain elements from the         DTD(documentTypeImpl Object)</strong>
-				</a>
-				<a name="1357">
-					<em>Eric Ye <small>(Mon Jul 17 2000 - 21:49:54         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1358.html">
-					<strong>RE: Cannot obtain elements from the         DTD(documentTypeImpl Object)</strong>
-				</a>
-				<a name="1358">
-					<em>Grengbondai, Jules C. <small>(Mon Jul 17 2000 -         21:58:37 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1359.html">
-					<strong>Special characters</strong>
-				</a>
-				<a name="1359">
-					<em>         Igor Seletskiy <small>(Mon Jul 17 2000 - 22:20:50         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1360.html">
-					<strong>RE: Cannot obtain elements from the         DTD(documentTypeImpl Object)</strong>
-				</a>
-				<a name="1360">
-					<em>Jeffrey Rodriguez <small>(Mon Jul 17 2000 - 22:35:54         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1361.html">
-					<strong>Re: REDOM Design discussion.</strong>
-				</a>
-				<a name="1361">
-					<em>James Duncan Davidson <small>(Tue Jul 18 2000 -         00:28:02 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1362.html">
-					<strong>Re: [Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1362">
-					<em>James Duncan Davidson <small>(Tue Jul 18 2000 -         00:30:08 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1363.html">
-					<strong>Re: [XRI] XRI requirements list posted to Apache         website</strong>
-				</a>
-				<a name="1363">
-					<em>James Duncan         Davidson <small>(Tue Jul 18 2000 - 00:41:10         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1364.html">
-					<strong>Re: XRI requirements - and overdefensiveness in         OpenSourceLand...</strong>
-				</a>
-				<a name="1364">
-					<em>James         Duncan Davidson <small>(Tue Jul 18 2000 - 00:53:14         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1365.html">
-					<strong>Re: [Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1365">
-					<em>Mike Pogue <small>(Tue Jul 18 2000 - 01:45:44         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1366.html">
-					<strong>Re: XRI requirements - and overdefensiveness in         OpenSourceLand...</strong>
-				</a>
-				<a name="1366">
-					<em>Mike         Pogue <small>(Tue Jul 18 2000 - 01:48:48         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1367.html">
-					<strong>Re: Special characters</strong>
-				</a>
-				<a name="1367">
-					<em>Mike Pogue <small>(Tue Jul 18 2000 - 01:49:22         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1368.html">
-					<strong>RE: An extensibility framework for Xerces and its         clients?</strong>
-				</a>
-				<a name="1368">
-					<em>Paulo Gaspar         <small>(Tue Jul 18 2000 - 02:44:46 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1369.html">
-					<strong>RE: REDOM Design discussion.</strong>
-				</a>
-				<a name="1369">
-					<em>Paulo Gaspar <small>(Tue Jul 18 2000 - 02:49:20         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1370.html">
-					<strong>RE: REDOM Design discussion.</strong>
-				</a>
-				<a name="1370">
-					<em>Paulo Gaspar <small>(Tue Jul 18 2000 - 02:51:47         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1371.html">
-					<strong>RE: [Xerces2] What is CORE?</strong>
-				</a>
-				<a name="1371">
-					<em>Paulo Gaspar <small>(Tue Jul 18 2000 - 03:37:20         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1372.html">
-					<strong>The Deferred DOM (was Re: REDOM Design         discussion.)</strong>
-				</a>
-				<a name="1372">
-					<em>Arnaud Le Hors         <small>(Tue Jul 18 2000 - 03:50:57 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1375.html">
-					<strong>NodeContainer (was Re: entity resolution with         schema validation)</strong>
-				</a>
-				<a name="1375">
-					<em>Arnaud         Le Hors <small>(Tue Jul 18 2000 - 03:51:15         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1373.html">
-					<strong>Managing/implementing several DOM         implementations</strong>
-				</a>
-				<a name="1373">
-					<em>Arnaud Le         Hors <small>(Tue Jul 18 2000 - 03:51:32         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1374.html">
-					<strong>Re: Stupid Question (ints,string)</strong>
-				</a>
-				<a name="1374">
-					<em>Arnaud Le Hors <small>(Tue Jul 18 2000 -         03:52:11 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1376.html">
-					<strong>RE: Managing/implementing several DOM         implementations</strong>
-				</a>
-				<a name="1376">
-					<em>Paulo         Gaspar <small>(Tue Jul 18 2000 - 04:52:39         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1377.html">
-					<strong>Re: The Deferred DOM (was Re: REDOM Design         discussion.)</strong>
-				</a>
-				<a name="1377">
-					<em>Ryan Schmidt         <small>(Tue Jul 18 2000 - 04:54:48 MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1378.html">
-					<strong>Re: BUG: SAXParser endElement reports incorrect         local name w/ namespaces</strong>
-				</a>
-				<a name="1378">
-					<em>         Jeffrey Rodriguez <small>(Tue Jul 18 2000 - 05:50:47         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1379.html">
-					<strong>Xerces Redesign</strong>
-				</a>
-				<a name="1379">
-					<em>         Andy Clark <small>(Tue Jul 18 2000 - 06:09:44         MEST)</small>
-					</em>
-				</a>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-xerces-j-dev/1380.html">
-					<strong>Re: setValidating method</strong>
-				</a>
-				<a name="1380">
-					<em>Martin Fuhrer <small>(Tue Jul 18 2000 - 09:36:31         MEST)</small>
-					</em>
-				</a>
-			</li>
-		</mailHeaderSet>
-		<mailHeaderSet id="gen">
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2091.html">
-					<strong>[spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2091">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Sat Jul         08 2000 - 07:31:16 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2092.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2092">
-					<em>Andy Clark</em>
-				</a>&nbsp;<em>(Sat Jul 08 2000 -         09:22:28 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2093.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2093">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Sat Jul 08         2000 - 19:56:58 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2094.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2094">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Sat Jul         08 2000 - 23:46:00 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2095.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2095">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Sun Jul         09 2000 - 00:10:51 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2096.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2096">
-					<em>Arved Sandstrom</em>
-				</a>&nbsp;<em>(Sun Jul 09         2000 - 00:31:25 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2097.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2097">
-					<em>Kevin Regan</em>
-				</a>&nbsp;<em>(Sun Jul 09 2000 -         00:41:41 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2098.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2098">
-					<em>burtonator</em>
-				</a>&nbsp;<em>(Sun Jul 09 2000 -         05:19:38 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2099.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2099">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Sun Jul         09 2000 - 07:04:49 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2100.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2100">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Sun Jul         09 2000 - 07:38:44 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2101.html">
-					<strong>Xerces-J download</strong>
-				</a>&nbsp;<a name="2101">
-					<em>Krassimir Dimov</em>
-				</a>&nbsp;<em>(Sun Jul 09 2000 -         09:34:56 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2102.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2102">
-					<em>Arved Sandstrom</em>
-				</a>&nbsp;<em>(Sun Jul 09         2000 - 13:55:20 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2103.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2103">
-					<em>Stefano Mazzocchi</em>
-				</a>&nbsp;<em>(Sun Jul 09         2000 - 17:36:18 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2104.html">
-					<strong>design docs and diagrams [was Re: [spinnaker]         Announce]</strong>
-				</a>&nbsp;<a name="2104">
-					<em>Randall J.         Parr</em>
-				</a>&nbsp;<em>(Sun Jul 09 2000 - 18:43:49         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2105.html">
-					<strong>Re: design docs and diagrams</strong>
-				</a>&nbsp;<a name="2105">
-					<em>Guy Hulbert</em>
-				</a>&nbsp;<em>(Sun Jul 09         2000 - 18:55:54 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2106.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2106">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Sun Jul         09 2000 - 23:32:40 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2107.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2107">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 00:12:30 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2108.html">
-					<strong>[spinnaker] XML Hack Article</strong>
-				</a>&nbsp;<a name="2108">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>         (Mon Jul 10 2000 - 00:47:01 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2109.html">
-					<strong>Re: design docs and diagrams</strong>
-				</a>&nbsp;<a name="2109">
-					<em>Arved Sandstrom</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 01:56:41 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2110.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2110">
-					<em>MITCHELL SOJDEHEI</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 02:57:49 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2111.html">
-					<strong>RE: Entities not supported in         DTDs</strong>
-				</a>&nbsp;<a name="2111">
-					<em>Peter Guldbaek -         Netnord A/S</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000 - 07:25:46         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2112.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2112">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 07:41:06 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2113.html">
-					<strong>Re: design docs and diagrams</strong>
-				</a>&nbsp;<a name="2113">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>         (Mon Jul 10 2000 - 08:05:16 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2114.html">
-					<strong>RE: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2114">
-					<em>GOMEZ Henri</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000 -         08:25:20 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2115.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2115">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 12:29:40 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2116.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2116">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 12:38:31 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2117.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2117">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 16:55:02 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2118.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2118">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 17:37:28 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2119.html">
-					<strong>Re: XML Database</strong>
-				</a>&nbsp;<a name="2119">
-					<em>Falko Braeutigam</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000 -         16:29:23 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2120.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2120">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 18:22:17 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2121.html">
-					<strong>Re: Xerces-J download</strong>
-				</a>&nbsp;<a name="2121">
-					<em>Jeffrey Rodriguez</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 19:51:53 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2122.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2122">
-					<em>costin@eng.sun.com</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 19:54:06 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2123.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2123">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000 -         19:35:39 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2124.html">
-					<strong>Re: Xerces-J download</strong>
-				</a>&nbsp;<a name="2124">
-					<em>Krassimir Dimov</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 20:39:52 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2125.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2125">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000 -         20:47:58 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2126.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2126">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000 -         21:10:43 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2127.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2127">
-					<em>Stefano Mazzocchi</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 21:14:31 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2128.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2128">
-					<em>Rajiv Mordani</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000         - 22:11:48 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2129.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2129">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 22:32:01 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2130.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2130">
-					<em>costin@eng.sun.com</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 22:48:38 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2131.html">
-					<strong>RE: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2131">
-					<em>Eric Hodges</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000 -         22:44:13 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2132.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2132">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 23:00:34 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2133.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2133">
-					<em>Joe Polastre</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000         - 23:05:18 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2134.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2134">
-					<em>Rajiv Mordani</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000         - 23:11:35 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2135.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2135">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 23:11:32 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2136.html">
-					<strong>Xalan Extensions &amp; Tomcat Class         Loader</strong>
-				</a>&nbsp;<a name="2136">
-					<em>Roytman,         Alex</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000 - 23:18:49         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2137.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2137">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 23:18:08 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2138.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2138">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000 -         23:18:54 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2139.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2139">
-					<em>Jim Driscoll</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000         - 23:31:05 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2140.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2140">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 23:32:47 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2141.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2141">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 23:36:31 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2142.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2142">
-					<em>costin@eng.sun.com</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 23:37:05 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2143.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2143">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 23:38:01 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2144.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2144">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 23:34:54 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2145.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2145">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Mon Jul         10 2000 - 23:43:44 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2146.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2146">
-					<em>Arved Sandstrom</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 23:48:51 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2147.html">
-					<strong>RE: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2147">
-					<em>Eric Hodges</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000 -         23:47:08 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2148.html">
-					<strong>HotSpot Bashing (was RE: [spinnaker]         Announce)</strong>
-				</a>&nbsp;<a name="2148">
-					<em>Eric         Hodges</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 - 00:17:00         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2149.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2149">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 00:37:40 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2150.html">
-					<strong>Re: HotSpot Bashing (was RE: [spinnaker]         Announce)</strong>
-				</a>&nbsp;<a name="2150">
-					<em>         costin@eng.sun.com</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         00:55:24 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2151.html">
-					<strong>Re: HotSpot Bashing (was RE: [spinnaker]         Announce)</strong>
-				</a>&nbsp;<a name="2151">
-					<em>James Duncan         Davidson</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 - 01:20:41         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2152.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2152">
-					<em>rubys@us.ibm.com</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 02:07:44 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2153.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2153">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 02:43:43 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2154.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2154">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 03:41:05 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2155.html">
-					<strong>Re: XML Database</strong>
-				</a>&nbsp;<a name="2155">
-					<em>Joseph Shraibman</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         03:47:55 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2156.html">
-					<strong>Re: [spinnaker] Can't we all work         together?</strong>
-				</a>&nbsp;<a name="2156">
-					<em>         rubys@us.ibm.com</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         03:44:22 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2157.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2157">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         04:13:38 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2158.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2158">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 04:51:43 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2159.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2159">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 05:20:52 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2160.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2160">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 05:13:33 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2161.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2161">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 05:25:51 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2162.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2162">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 05:54:01 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2163.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2163">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 06:05:54 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2164.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2164">
-					<em>Jeffrey Rodriguez</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 06:21:14 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2165.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2165">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 06:25:05 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2166.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2166">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 06:47:55 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2167.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2167">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 07:06:26 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2168.html">
-					<strong>Re: XML Database</strong>
-				</a>&nbsp;<a name="2168">
-					<em>Brian Tol</em>
-				</a>&nbsp;<em>(Fri Jul 07 2000 - 22:22:21         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2169.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2169">
-					<em>Jeffrey Rodriguez</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 08:00:06 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2170.html">
-					<strong>RE: XML Database</strong>
-				</a>&nbsp;<a name="2170">
-					<em>steven.noels@the-ecorp.com</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 10:07:47 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2171.html">
-					<strong>Re: Xerces-J download</strong>
-				</a>&nbsp;<a name="2171">
-					<em>Jeffrey Rodriguez</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 11:12:54 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2172.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2172">
-					<em>twleung@sauria.com</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 12:45:28 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2173.html">
-					<strong>[XRI] Xerces Refactoring         Initiative</strong>
-				</a>&nbsp;<a name="2173">
-					<em>         rubys@us.ibm.com</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         12:51:17 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2174.html">
-					<strong>RE: XML Database</strong>
-				</a>&nbsp;<a name="2174">
-					<em>Paulo Gaspar</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         13:15:23 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2175.html">
-					<strong>Re: [XRI] Xerces Refactoring         Initiative</strong>
-				</a>&nbsp;<a name="2175">
-					<em>N. Sean         Timm</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 - 13:22:41         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2176.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2176">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 14:08:26 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2177.html">
-					<strong>Re: [XRI] Xerces Refactoring         Initiative</strong>
-				</a>&nbsp;<a name="2177">
-					<em>         rubys@us.ibm.com</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         14:12:12 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2178.html">
-					<strong>RE: [XRI] Xerces Refactoring         Initiative</strong>
-				</a>&nbsp;<a name="2178">
-					<em>Ed         Staub</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 - 16:30:21         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2179.html">
-					<strong>RE: [XRI] Xerces Refactoring         Initiative</strong>
-				</a>&nbsp;<a name="2179">
-					<em>Crook,         Charles</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 - 16:48:12         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2180.html">
-					<strong>RE: [XRI] Xerces Refactoring         Initiative</strong>
-				</a>&nbsp;<a name="2180">
-					<em>HERRICK,         CHUCK (SBCSI)</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 - 17:17:33         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2181.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2181">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         18:49:11 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2182.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2182">
-					<em>Andy Heninger</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000         - 18:59:24 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2183.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2183">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         19:04:56 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2184.html">
-					<strong>Let's move on!</strong>
-				</a>&nbsp;<a name="2184">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         19:37:12 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2185.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2185">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         21:42:51 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2189.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2189">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         22:08:07 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2186.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2186">
-					<em>Brett McLaughlin</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 22:17:03 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2187.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2187">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         22:19:47 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2188.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2188">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         21:52:03 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2190.html">
-					<strong>Re: [XRI] Xerces Refactoring         Initiative</strong>
-				</a>&nbsp;<a name="2190">
-					<em>James         Duncan Davidson</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         22:31:26 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2191.html">
-					<strong>Re: Let's move on!</strong>
-				</a>&nbsp;<a name="2191">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         22:34:06 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2195.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2195">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         22:37:36 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2192.html">
-					<strong>What name?</strong>
-				</a>&nbsp;<a name="2192">
-					<em>         Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         22:54:13 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2193.html">
-					<strong>Re: XML Database</strong>
-				</a>&nbsp;<a name="2193">
-					<em>Edward Q. Bridges</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         19:41:36 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2194.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2194">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 22:39:19 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2196.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2196">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Tue Jul         11 2000 - 22:19:35 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2197.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2197">
-					<em>Brett McLaughlin</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         23:18:22 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2198.html">
-					<strong>[ANN] Xalan-J 1.1 Point Release posted to         xml.apache.org</strong>
-				</a>&nbsp;<a name="2198">
-					<em>         Shane_Curcuru@lotus.com</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000         - 23:20:29 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2199.html">
-					<strong>Re: [ANN] Xalan-J 1.1 Point Release posted to         xml.apache.org</strong>
-				</a>&nbsp;<a name="2199">
-					<em>Jeffrey         Rodriguez</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 - 23:30:48         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2200.html">
-					<strong>Xerces calls SAXParserFactoryImpl but doesn't have         it?</strong>
-				</a>&nbsp;<a name="2200">
-					<em>Longstrom,         Ed</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 - 23:35:41 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2201.html">
-					<strong>Re: XML Database</strong>
-				</a>&nbsp;<a name="2201">
-					<em>Tom Bradford</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         23:38:32 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2202.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2202">
-					<em>Joe Polastre</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         23:46:24 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2203.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2203">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         23:42:10 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2204.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2204">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 -         23:57:57 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2205.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2205">
-					<em>Brett McLaughlin</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         00:22:49 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2206.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2206">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 00:14:42 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2207.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2207">
-					<em>Brett         McLaughlin</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 00:28:32         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2208.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2208">
-					<em>Brett McLaughlin</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         00:36:54 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2209.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2209">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul         12 2000 - 00:25:18 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2210.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2210">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         00:44:03 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2211.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2211">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         00:46:34 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2212.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2212">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 00:53:46         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2213.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2213">
-					<em>Brett         McLaughlin</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 01:02:27         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2214.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2214">
-					<em>Joe Polastre</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         00:53:40 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2215.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2215">
-					<em>James         Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         00:58:46 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2216.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2216">
-					<em>Andy Heninger</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         01:01:25 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2217.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2217">
-					<em>Arved Sandstrom</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 01:03:03 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2218.html">
-					<strong>RE: What name?</strong>
-				</a>&nbsp;<a name="2218">
-					<em>HERRICK, CHUCK (SBCSI)</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 00:29:43 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2219.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2219">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 01:08:45 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2220.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2220">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul         12 2000 - 01:11:58 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2221.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2221">
-					<em>James         Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         01:15:59 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2222.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2222">
-					<em>Eric Hodges</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         01:23:23 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2223.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2223">
-					<em>Rod McChesney</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000         - 01:32:31 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2224.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2224">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 01:35:50         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2225.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2225">
-					<em>Stefano Mazzocchi</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 15:20:18 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2228.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2228">
-					<em>Stefano Mazzocchi</em>
-				</a>&nbsp;<em>(Tue Jul 11         2000 - 15:25:39 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2227.html">
-					<strong>Re: [XRI] Xerces Refactoring         Initiative</strong>
-				</a>&nbsp;<a name="2227">
-					<em>Stefano         Mazzocchi</em>
-				</a>&nbsp;<em>(Tue Jul 11 2000 - 15:33:04         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2226.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2226">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 01:39:34 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2229.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2229">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 01:44:51 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2230.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2230">
-					<em>Joe Polastre</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000         - 01:43:17 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2231.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2231">
-					<em>Joe Polastre</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         01:47:23 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2232.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2232">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         01:52:27 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2233.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2233">
-					<em>Randall         J. Parr</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 01:52:27         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2234.html">
-					<strong>RE: What name?</strong>
-				</a>&nbsp;<a name="2234">
-					<em>HERRICK, CHUCK (SBCSI)</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 01:55:22 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2235.html">
-					<strong>RE: What name?</strong>
-				</a>&nbsp;<a name="2235">
-					<em>HERRICK, CHUCK (SBCSI)</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 01:57:29 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2236.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2236">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 01:59:59 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2237.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2237">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         02:13:53 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2238.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2238">
-					<em>James         Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         02:15:55 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2239.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2239">
-					<em>Andy Heninger</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         02:25:53 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2240.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2240">
-					<em>Costin         Manolache</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:31:12         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2241.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2241">
-					<em>Arved Sandstrom</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 02:22:53 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2242.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2242">
-					<em>Eric         Ye</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:48:42 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2243.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2243">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:49:04         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2244.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2244">
-					<em>Eric Ye</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         02:51:31 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2245.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2245">
-					<em>Donald         Ball</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:57:59         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2246.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2246">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul         12 2000 - 02:55:07 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2247.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2247">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 02:56:56 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2248.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2248">
-					<em>Eric Hodges</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         03:03:32 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2249.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2249">
-					<em>Brett         McLaughlin</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 03:07:59         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2250.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2250">
-					<em>Joe         Polastre</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 03:11:02         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2251.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2251">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 03:22:05         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2252.html">
-					<strong>[spinnaker] proposal: move spinnaker to         xml-xerces/proposals /spinnaker</strong>
-				</a>&nbsp;<a name="2252">
-					<em>rubys@us.ibm.com</em>
-				</a>&nbsp;<em>(Mon Jul 10         2000 - 22:49:53 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2253.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2253">
-					<em>James         Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         04:12:50 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2254.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2254">
-					<em>James         Duncan Davidson</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         04:15:37 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2255.html">
-					<strong>javax.xml support</strong>
-				</a>&nbsp;<a name="2255">
-					<em>Szegedi, Attila</em>
-				</a>&nbsp;<em>(Mon Jul 10 2000 -         17:10:56 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2256.html">
-					<strong>Re: javax.xml support</strong>
-				</a>&nbsp;<a name="2256">
-					<em>Christopher Elkins</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 04:37:42 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2257.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2257">
-					<em>N. Sean         Timm</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 05:59:47         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2258.html">
-					<strong>XRI requirements</strong>
-				</a>&nbsp;<a name="2258">
-					<em>Ed Staub</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 06:03:53         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2259.html">
-					<strong>Re: [spinnaker] proposal: move spinnaker to         xml-xerces/proposals/spinnaker</strong>
-				</a>&nbsp;<a name="2259">
-					<em>N. Sean Timm</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000         - 06:10:48 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2260.html">
-					<strong>Fwd: Re: javax.xml support</strong>
-				</a>&nbsp;<a name="2260">
-					<em>Jeffrey Rodriguez</em>
-				</a>&nbsp;<em>(Wed         Jul 12 2000 - 06:42:55 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2261.html">
-					<strong>Re: XRI requirements</strong>
-				</a>&nbsp;<a name="2261">
-					<em>Jeffrey Rodriguez</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 07:01:23 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2262.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2262">
-					<em>Jason         Hunter</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 07:56:29         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2263.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2263">
-					<em>Jason         Hunter</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 07:51:22         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2264.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2264">
-					<em>Jeffrey Rodriguez</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 10:19:36 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2265.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2265">
-					<em>Jeffrey         Rodriguez</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 10:52:30         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2266.html">
-					<strong>AW: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2266">
-					<em>Henning von Bargen</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 11:26:17 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2267.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2267">
-					<em>Stefano Mazzocchi</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 02:20:14 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2268.html">
-					<strong>Restoring original signal/noise         ratio</strong>
-				</a>&nbsp;<a name="2268">
-					<em>Stefano         Mazzocchi</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 02:43:02         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2269.html">
-					<strong>Re: Restoring original signal/noise         ratio</strong>
-				</a>&nbsp;<a name="2269">
-					<em>         rubys@us.ibm.com</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         14:36:46 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2270.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2270">
-					<em>Stefano Mazzocchi</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 14:52:54 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2273.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2273">
-					<em>Stefano Mazzocchi</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 14:56:53 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2272.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2272">
-					<em>Stefano         Mazzocchi</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 15:00:16         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2271.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2271">
-					<em>Stefano         Mazzocchi</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 15:02:47         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2274.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2274">
-					<em>Brett         McLaughlin</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 16:01:02         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2275.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2275">
-					<em>Brett         McLaughlin</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 16:07:32         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2276.html">
-					<strong>RE: XRI requirements</strong>
-				</a>&nbsp;<a name="2276">
-					<em>James Snell</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         07:25:50 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2277.html">
-					<strong>[ANN] Xalan-C 0.40.0 posted to         xml.apache.org</strong>
-				</a>&nbsp;<a name="2277">
-					<em>         David_N_Bertoni@lotus.com</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 17:49:29 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2278.html">
-					<strong>deprecated apis in xml4j</strong>
-				</a>&nbsp;<a name="2278">
-					<em>Muktavaram, Vikas (FUSA)</em>
-				</a>&nbsp;<em>(Wed         Jul 12 2000 - 17:46:55 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2279.html">
-					<strong>Re: Restoring original signal/noise         ratio</strong>
-				</a>&nbsp;<a name="2279">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 18:05:18         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2280.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2280">
-					<em>Octav         Chipara</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 18:41:29         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2281.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2281">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 19:02:01         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2282.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2282">
-					<em>Octav         Chipara</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 19:20:41         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2283.html">
-					<strong>Re: XRI requirements</strong>
-				</a>&nbsp;<a name="2283">
-					<em>Eric Ye</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         19:25:41 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2284.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2284">
-					<em>Eduardo         Pelegri--Llopart</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         19:31:22 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2285.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2285">
-					<em>Jeffrey         Rodriguez</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 19:38:42         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2286.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2286">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         19:41:29 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2287.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2287">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         19:42:47 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2288.html">
-					<strong>[Xerces2] Requirements list; 'Xerces2'?;         cross-posting</strong>
-				</a>&nbsp;<a name="2288">
-					<em>Ed         Staub</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 19:55:52         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2289.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2289">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 19:50:14         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2290.html">
-					<strong>Re: [Xerces2] Requirements list; 'Xerces2'?;         cross-posting</strong>
-				</a>&nbsp;<a name="2290">
-					<em>Octav         Chipara</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 19:50:59         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2291.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2291">
-					<em>Joe Polastre</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000         - 19:59:28 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2292.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2292">
-					<em>Octav         Chipara</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 20:01:51         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2294.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2294">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         18:42:01 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2296.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2296">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         19:59:46 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2295.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2295">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         18:52:11 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2293.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2293">
-					<em>Brett         McLaughlin</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 20:13:42         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2297.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2297">
-					<em>Arnaud Le Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         20:20:43 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2298.html">
-					<strong>Re: [Xerces2] Requirements list; 'Xerces2'?;         cross-posting</strong>
-				</a>&nbsp;<a name="2298">
-					<em>Arnaud         Le Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 20:46:38         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2299.html">
-					<strong>Re: What name?</strong>
-				</a>&nbsp;<a name="2299">
-					<em>Edwin Goei</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         21:15:51 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2300.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2300">
-					<em>Donald         Ball</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 21:21:13         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2301.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2301">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 21:19:06         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2302.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2302">
-					<em>Octav         Chipara</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 21:39:55         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2303.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2303">
-					<em>Octav         Chipara</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 22:05:45         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2304.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2304">
-					<em>Arved Sandstrom</em>
-				</a>&nbsp;<em>(Wed Jul 12         2000 - 22:14:57 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2305.html">
-					<strong>RE: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2305">
-					<em>Eric         Hodges</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 22:37:59         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2306.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2306">
-					<em>Edwin         Goei</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 23:05:01         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2311.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2311">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul         12 2000 - 23:44:52 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2307.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2307">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 - 23:54:10         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2308.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2308">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         21:13:50 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2310.html">
-					<strong>Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2310">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul         12 2000 - 21:46:16 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2309.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2309">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         21:31:24 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2312.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2312">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Wed Jul 12 2000 -         21:50:35 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2313.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2313">
-					<em>Tom Bradford</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000         - 00:08:47 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2314.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2314">
-					<em>Brett         McLaughlin</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 - 00:18:09         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2315.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2315">
-					<em>Octav         Chipara</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 - 00:23:10         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2316.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2316">
-					<em>Octav Chipara</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000         - 00:36:37 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2317.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2317">
-					<em>Joe Polastre</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000         - 00:40:24 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2318.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2318">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 -         00:50:27 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2319.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2319">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Thu Jul         13 2000 - 01:10:37 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2320.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2320">
-					<em>Stefano         Mazzocchi</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 - 01:11:58         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2321.html">
-					<strong>Re: [Xerces2] Requirements list; 'Xerces2'?;         cross-posting</strong>
-				</a>&nbsp;<a name="2321">
-					<em>Stefano         Mazzocchi</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 - 01:13:00         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2322.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2322">
-					<em>Eric         Hodges</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 - 01:57:10         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2323.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2323">
-					<em>Ted Leung</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 -         02:08:55 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2324.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2324">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Thu Jul         13 2000 - 02:26:42 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2325.html">
-					<strong>Re: XRI requirements</strong>
-				</a>&nbsp;<a name="2325">
-					<em>Ted Leung</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 -         02:25:56 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2326.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2326">
-					<em>Tim         Bray</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 - 02:33:14         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2327.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2327">
-					<em>rubys@us.ibm.com</em>
-				</a>&nbsp;<em>(Thu Jul 13         2000 - 02:37:30 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2328.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2328">
-					<em>Joe Polastre</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000         - 02:39:30 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2329.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2329">
-					<em>Arnaud Le         Hors</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 - 02:46:08         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2330.html">
-					<strong>RE: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2330">
-					<em>Ed Staub</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 -         03:29:30 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2331.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2331">
-					<em>Edwin         Goei</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 - 04:27:46         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2332.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2332">
-					<em>Eric Hodges</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 -         05:42:17 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2333.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2333">
-					<em>Ted Leung</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 -         06:46:09 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2334.html">
-					<strong>AW: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2334">
-					<em>Henning von Bargen</em>
-				</a>&nbsp;<em>(Thu Jul 13         2000 - 08:57:46 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2335.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2335">
-					<em>Eric Hodges</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 -         09:15:49 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2336.html">
-					<strong>Re: javax.xml support</strong>
-				</a>&nbsp;<a name="2336">
-					<em>Rajiv Mordani</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000         - 09:42:39 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2337.html">
-					<strong>Re: [spinnaker] proposal: move spinnaker to         xml-xerces/proposals/spinnaker</strong>
-				</a>&nbsp;<a name="2337">
-					<em>Rajiv Mordani</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000         - 09:45:06 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2338.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2338">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 -         06:07:25 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2339.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2339">
-					<em>Scott         Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 -         06:12:28 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2340.html">
-					<strong>RE: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2340">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Thu Jul         13 2000 - 06:29:25 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2341.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2341">
-					<em>Stefano Mazzocchi</em>
-				</a>&nbsp;<em>(Thu Jul 13         2000 - 01:52:43 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2342.html">
-					<strong>Generation of Static Pages using the         Cache</strong>
-				</a>&nbsp;<a name="2342">
-					<em>Bob Van         Cleef</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 - 18:06:48         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2343.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2343">
-					<em>Thomas B. Passin</em>
-				</a>&nbsp;<em>(Thu Jul 13         2000 - 19:28:10 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2344.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2344">
-					<em>Thomas B. Passin</em>
-				</a>&nbsp;<em>(Thu Jul 13         2000 - 19:33:11 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2345.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2345">
-					<em>costin@eng.sun.com</em>
-				</a>&nbsp;<em>(Thu Jul 13         2000 - 21:46:20 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2346.html">
-					<strong>Re: [spinnaker] proposal: move spinnaker to         xml-xerces/proposals /spinnaker</strong>
-				</a>&nbsp;<a name="2346">
-					<em>rubys@us.ibm.com</em>
-				</a>&nbsp;<em>(Thu Jul 13         2000 - 16:35:20 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2347.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2347">
-					<em>James         Duncan Davidson</em>
-				</a>&nbsp;<em>(Fri Jul 14 2000 -         06:38:44 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2351.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2351">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Fri Jul         14 2000 - 06:38:44 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2348.html">
-					<strong>Re: XRI requirements</strong>
-				</a>&nbsp;<a name="2348">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Fri Jul         14 2000 - 06:38:44 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2349.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2349">
-					<em>James         Duncan Davidson</em>
-				</a>&nbsp;<em>(Fri Jul 14 2000 -         06:38:44 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2350.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2350">
-					<em>James         Duncan Davidson</em>
-				</a>&nbsp;<em>(Fri Jul 14 2000 -         06:38:44 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2352.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2352">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Fri Jul         14 2000 - 06:38:44 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2353.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2353">
-					<em>Jeffrey Rodriguez</em>
-				</a>&nbsp;<em>(Fri Jul 14         2000 - 09:07:29 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2354.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2354">
-					<em>Stefano         Mazzocchi</em>
-				</a>&nbsp;<em>(Thu Jul 13 2000 - 14:42:49         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2355.html">
-					<strong>RE: XRI requirements</strong>
-				</a>&nbsp;<a name="2355">
-					<em>Ed Staub</em>
-				</a>&nbsp;<em>(Fri Jul 14 2000 -         14:03:26 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2356.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2356">
-					<em>Arved         Sandstrom</em>
-				</a>&nbsp;<em>(Fri Jul 14 2000 - 16:11:08         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2357.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2357">
-					<em>Octav         Chipara</em>
-				</a>&nbsp;<em>(Fri Jul 14 2000 - 17:42:09         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2358.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2358">
-					<em>Jeffrey         Rodriguez</em>
-				</a>&nbsp;<em>(Fri Jul 14 2000 - 18:40:14         MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2359.html">
-					<strong>Re: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2359">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Fri Jul         14 2000 - 18:40:06 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2360.html">
-					<strong>Re: XRI requirements</strong>
-				</a>&nbsp;<a name="2360">
-					<em>James Duncan Davidson</em>
-				</a>&nbsp;<em>(Fri Jul         14 2000 - 18:52:35 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2361.html">
-					<strong>Re: parser-next-gen goals, plan, and         requirements</strong>
-				</a>&nbsp;<a name="2361">
-					<em>James         Duncan Davidson</em>
-				</a>&nbsp;<em>(Fri Jul 14 2000 -         18:54:42 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2362.html">
-					<strong>RE: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2362">
-					<em>Paulo Gaspar</em>
-				</a>&nbsp;<em>(Fri Jul 14 2000         - 19:34:13 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2363.html">
-					<strong>RE: Microsoft XML stuff</strong>
-				</a>&nbsp;<a name="2363">
-					<em>Paulo Gaspar</em>
-				</a>&nbsp;<em>(Fri Jul 14 2000         - 19:36:37 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2364.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2364">
-					<em>Jim Driscoll</em>
-				</a>&nbsp;<em>(Fri Jul 14 2000         - 20:25:44 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2365.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2365">
-					<em>Joe Polastre</em>
-				</a>&nbsp;<em>(Fri Jul 14 2000         - 20:41:21 MEST)</em>
-			</li>
-			<li>
-				<a href="http://xml-archive.webweaving.org/xml-archive-general/2366.html">
-					<strong>Re: [spinnaker] Announce</strong>
-				</a>&nbsp;<a name="2366">
-					<em>Scott Boag/CAM/Lotus</em>
-				</a>&nbsp;<em>(Fri Jul         14 2000 - 21:31:30 MEST)</em>
-			</li>
-		</mailHeaderSet>
-	</mailHeaderSets>
-</requirementCatalog>
diff --git a/proposals/XRI-requirements/issues.xsl b/proposals/XRI-requirements/issues.xsl
deleted file mode 100644
index 7b67407..0000000
--- a/proposals/XRI-requirements/issues.xsl
+++ /dev/null
@@ -1,191 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- define nbsp char entity for output -->
-<!DOCTYPE menu [
-	<!ENTITY nbsp "&#160;">
-]>
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
-	<xsl:output media-type="text/html" encoding="UTF-8"/>
-	<xsl:template match="/">
-		<html>
-			<head>
-				<title>Proposed Xerces2 Requirements -  <xsl:value-of select="/requirementCatalog/@date"/>
-				</title>
-			</head>
-			<body bgcolor="#FFFFFF">
-				<h1>Proposed Xerces2 Requirements</h1>
-				<h4>Date: <xsl:value-of select="/requirementCatalog/@date"/>
-					<br/>
-  Editors: &nbsp;&nbsp;<a href="mailto:estaub@mediaone.net">Ed Staub</a>&nbsp;&nbsp;<a href="mailto:twleung@sauria.com">Ted Leung</a>
-				</h4>
-				<hr/>
-				<h2>Schema</h2>
-				<p>Proposed requirements are organized into categories. &nbsp;Some requirements 
-  occur in more than one category in the future.</p>
-				<p>Each requirement has a number. Underneath the number is a &quot;hardness&quot; 
-  and &quot;status&quot;.</p>
-				<dl>
-					<dt>Possible &quot;hardness&quot; values are:</dt>
-					<dd>
-						<b>hard</b> - Xerces2 must and shall meet this requirement<br/>
-						<b>soft</b> - Xerces2 should meet this requirement, but it may be dropped 
-    because of conflicting requirements or time pressures</dd>
-					<dt>
-						<br/>
-    Possible &quot;status&quot; values are:</dt>
-					<dd>
-						<b>approved</b> - there appears to be a clear consensus<br/>
-						<b>tooQuiet</b> - there may be a consensus, but there hasn't been enough 
-    input to be sure <br/>
-						<b>hardnessConflict</b> - there is conflict over whether this is a hard or 
-    soft requirement<b>
-							<br/>
-    vetoConflict</b> - there is a conflict over whether this proposed requirement 
-    is a requirement at all<br/>
-						<b>rejected</b> - the proposed requirement appears to be dead<br/>
-						<b>unevaluated</b> - editor hasn't finished reviewing input
-					</dd>
-				</dl>
-				<hr/>
-				<xsl:apply-templates/>
-			</body>
-		</html>
-	</xsl:template>
-	<xsl:template match="requirementCatalog">
-		<xsl:call-template name="indexByNumber"/>
-		<xsl:apply-templates select="categories" mode="toc"/>
-		<xsl:apply-templates select="categories"/>
-	</xsl:template>
-	<!-- Table of contents -->
-	<xsl:template match="categories" mode="toc">
-		<h2>Requirement Categories</h2>
-		<xsl:for-each select="cat">
-			<a>
-				<xsl:attribute name="href">#cat.{.}</xsl:attribute>
-				<xsl:value-of select="."/>
-			</a>
-			<br/>
-		</xsl:for-each>
-		<hr/>
-	</xsl:template>
-	<xsl:template name="indexByNumber">
-		<h2>Requirements by Number</h2>
-		<xsl:for-each select="/requirementCatalog/requirements/req">
-			<a href="#req.{@id}">
-				<xsl:value-of select="@id"/>
-			</a>&nbsp;	&nbsp;
-			<xsl:value-of select="substring(def,1,120)"/>
-			<xsl:if test="string-length(def)>120">...</xsl:if>
-			<br/>
-			<xsl:if test="@id mod 5 = 0">
-				<br/>
-			</xsl:if>
-		</xsl:for-each>
-		<hr/>
-	</xsl:template>
-	<xsl:template match="categories">
-		<h2>Requirements by Category</h2>
-		<xsl:for-each select="cat">
-			<h3>
-				<a>
-					<xsl:attribute name="name">#cat.{.}</xsl:attribute>
-				</a>
-				<xsl:value-of select="."/>
-			</h3>
-			<table width="95%" border="1">
-				<xsl:for-each select="/requirementCatalog/requirements/req[@cat=current()]">
-					<xsl:apply-templates select="."/>
-				</xsl:for-each>
-			</table>
-		</xsl:for-each>
-	</xsl:template>
-	<xsl:template match="req">
-		<xsl:variable name="reqId" select="@id"/>
-		<tr>
-			<td valign="top">
-				<p>
-					<a>
-						<xsl:attribute name="name">req.<xsl:value-of select="$reqId"/></xsl:attribute>
-					</a>
-					<b>
-						<!--						<xsl:value-of select="@id"/>.</b> -->
-						<xsl:value-of select="$reqId"/>.</b>
-					<br/>
-        &nbsp;&nbsp;<xsl:value-of select="@strength"/>
-					<br/>
-        &nbsp;&nbsp;<xsl:value-of select="@status"/>
-				</p>
-			</td>
-			<td valign="top">
-				<p>
-					<b>
-						<xsl:copy-of select="def"/>
-					</b>
-				</p>
-				<blockquote>
-					<xsl:if test="seeAlso">
-						<p><xsl:apply-templates select="seeAlso"/></p>
-					</xsl:if>
-					<xsl:apply-templates select="voteSet"/>
-					<xsl:apply-templates select="edReqNote"/>
-					<xsl:if test="refs/ref">
-						<b><i>References</i></b>
-						<br/>
-					</xsl:if>
-					<xsl:apply-templates select="refs/ref"/>
-				</blockquote>
-			</td>
-		</tr>
-	</xsl:template>
-	<xsl:template match="voteSet">
-		<b>
-			<i>Voted</i>
-		</b> on from <xsl:value-of select="@opened"/> to <xsl:value-of select="@closed"/>.  Votes:
-	<ul>
-			<xsl:apply-templates select="vote"/>
-		</ul>
-	</xsl:template>
-	<xsl:template match="vote">
-		<li>
-			<a href="mailto:{@email}">
-				<xsl:value-of select="@voter"/>
-			</a>: <xsl:value-of select="@vote"/>
-			<xsl:apply-templates select="voteComment"/>
-		</li>
-	</xsl:template>
-	<xsl:template match="voteComment">
-		<blockquote>
-			<xsl:copy-of select="."/>
-		</blockquote>
-	</xsl:template>
-	<xsl:template match="seeAlso">
-		<xsl:if test="@type">
-			<xsl:value-of select="concat(@type,':')"/>
-		</xsl:if>
-		<xsl:if test="not(@type)">
-			See also:
-		</xsl:if>
-		<a href="#req.{@id}">
-			<xsl:value-of select="@id"/>
-		</a>&nbsp;&nbsp;
-	</xsl:template>
-	<xsl:template match="edReqNote">
-		<blockquote>
-			<i>Ed:</i>
-			<xsl:value-of select="."/>
-		</blockquote>
-	</xsl:template>
-	<xsl:template match="ref">
-		<p>
-			<xsl:if test="string(.)">"<xsl:copy-of select="."/>"<br/>
-			</xsl:if>
-			<xsl:apply-templates select="/requirementCatalog/mailHeaderSets/mailHeaderSet[@id=current()/@set]/li[a/@name=current()/@id]"/>
-		</p>
-	</xsl:template>
-	<xsl:template match="li">
-		<xsl:copy-of select="."/>
-	</xsl:template>
-	<xsl:template match="br">
-		<br/>
-	</xsl:template>
-	<xsl:template match="mailHeaderSets"/>
-</xsl:stylesheet>
diff --git a/samples/Makefile b/samples/Makefile
deleted file mode 100644
index d8d87a9..0000000
--- a/samples/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Makefile for directory .
-
-TARGETS=
-
-DIRS = dom sax ui util
-
-TOP = ..
-include $(TOP)/src/Makefile.incl
diff --git a/samples/dom/DOMAddLines.java b/samples/dom/DOMAddLines.java
deleted file mode 100644
index 0b8c10b..0000000
--- a/samples/dom/DOMAddLines.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package dom;                    
-
-import java.io.*;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.w3c.dom.NamedNodeMap;
-import org.xml.sax.Locator;
-import org.xml.sax.helpers.*;
-import org.apache.xerces.dom.NodeImpl;
-import org.apache.xerces.framework.XMLAttrList;
-import org.apache.xerces.parsers.DOMParser;
-import org.apache.xerces.utils.QName;
-
-/**
- * A sample of Adding lines to the DOM Node. This sample program illustrates:
- * - How to override methods from  DocumentHandler ( XMLDocumentHandler) 
- * - How to turn off ignorable white spaces by overriding ignorableWhiteSpace
- * - How to use the SAX Locator to return row position ( line number of DOM element).
- * - How to attach user defined Objects to Nodes using method setUserData
- * This example relies on the following:
- * - Turning off the "fast" DOM so we can use set expansion to FULL 
- * @version
- */
-
-public class DOMAddLines extends DOMParser  {
-
-   /** Print writer. */
-   private PrintWriter out;
-   static private boolean NotIncludeIgnorableWhiteSpaces = false; 
-
-
-   public DOMAddLines( String inputName ) {
-      //fNodeExpansion = FULL; // faster than: this.setFeature("http://apache.org/xml/features/defer-node-expansion", false);
-
-      try {                        
-         this.setFeature( "http://apache.org/xml/features/dom/defer-node-expansion", false ); 
-         this.parse( inputName );
-         out = new PrintWriter(new OutputStreamWriter(System.out, "UTF8"));
-      } catch ( IOException e ) {
-         System.err.println( "except" + e );
-      } catch ( org.xml.sax.SAXException e ) {
-         System.err.println( "except" + e );
-      }
-   } // constructor
-
-   /** Prints the specified node, recursively. */
-   public void print(Node node) {
-      // is there anything to do?
-      if ( node == null ) {
-         return;
-      }
-
-      String lineRowColumn = (String ) ((NodeImpl) node).getUserData();
-
-      int type = node.getNodeType();
-      switch ( type ) {
-         // print document
-         case Node.DOCUMENT_NODE: {
-               out.println(  lineRowColumn + ":" + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-               print( ((Document)node).getDocumentElement());
-               out.flush();
-               break;
-            }
-
-            // print element with attributes
-         case Node.ELEMENT_NODE: {
-               out.print( lineRowColumn + ":" + '<');
-               out.print(node.getNodeName());
-               Attr attrs[] = sortAttributes(node.getAttributes());
-               for ( int i = 0; i < attrs.length; i++ ) {
-                  Attr attr = attrs[i];
-                  out.print(' ');
-                  out.print(attr.getNodeName());
-                  out.print("=\"");
-                  out.print( attr.getNodeValue());
-                  out.print('"');
-               }
-               out.print('>');
-               NodeList children = node.getChildNodes();
-               if ( children != null ) {
-                  int len = children.getLength();
-                  for ( int i = 0; i < len; i++ ) {
-                     print(children.item(i));
-                  }
-               }
-               break;
-            }
-
-            // handle entity reference nodes
-         case Node.ENTITY_REFERENCE_NODE: {
-               out.print('&');
-               out.print(node.getNodeName());
-               out.print(';');
-               break;
-            }
-
-            // print cdata sections
-         case Node.CDATA_SECTION_NODE: {
-               out.print("<![CDATA[");
-               out.print(node.getNodeValue());
-               out.print("]]>");
-               break;
-            }
-
-            // print text
-         case Node.TEXT_NODE: {
-               out.print(  node.getNodeValue());
-               break;
-            }
-
-            // print processing instruction
-         case Node.PROCESSING_INSTRUCTION_NODE: {
-               out.print("<?");
-               out.print(node.getNodeName());
-               String data = node.getNodeValue();
-               if ( data != null && data.length() > 0 ) {
-                  out.print(' ');
-                  out.print(data);
-               }
-               out.print("?>");
-               break;
-            }
-      }
-
-      if ( type == Node.ELEMENT_NODE ) {
-         out.print("</");
-         out.print(node.getNodeName());
-         out.print('>');
-      }
-
-      out.flush();
-
-   } // print(Node)
-
-
-   /** Returns a sorted list of attributes. */
-   private Attr[] sortAttributes(NamedNodeMap attrs) {
-
-      int len = (attrs != null) ? attrs.getLength() : 0;
-      Attr array[] = new Attr[len];
-      for ( int i = 0; i < len; i++ ) {
-         array[i] = (Attr)attrs.item(i);
-      }
-      for ( int i = 0; i < len - 1; i++ ) {
-         String name  = array[i].getNodeName();
-         int    index = i;
-         for ( int j = i + 1; j < len; j++ ) {
-            String curName = array[j].getNodeName();
-            if ( curName.compareTo(name) < 0 ) {
-               name  = curName;
-               index = j;
-            }
-         }
-         if ( index != i ) {
-            Attr temp    = array[i];
-            array[i]     = array[index];
-            array[index] = temp;
-         }
-      }
-
-      return (array);
-
-   } // sortAttributes(NamedNodeMap):Attr[]
-
-   /* Methods that we override */
-
-   /*   We override startElement callback  from DocumentHandler */
-
-   public void startElement(QName elementQName, XMLAttrList attrList, int attrListIndex) throws Exception 
-   {
-      super.startElement(elementQName, attrList, attrListIndex);
-
-      NodeImpl node = null;
-      try {
-      node = (NodeImpl) this.getProperty( "http://apache.org/xml/properties/dom/current-element-node" );
-      //System.out.println( "The node = " + node );  TODO JEFF
-      }
-      catch( org.xml.sax.SAXException ex )
-      {
-          System.err.println( "except" + ex );;
-      }
-      //NodeImpl node = (NodeImpl)getCurrentNode();       // Get current node
-      if( node != null )
-          node.setUserData(  String.valueOf( getLocator().getLineNumber() ) ); // Save location String into node
-   } //startElement 
-
-   /* We override startDocument callback from DocumentHandler */
-
-   public void startDocument(int versionIndex, int encodingIndex,
-                                   int standAloneIndex)
-   {
-     //super.startDocument( versionIndex, encodingIndex,
-     //                               standAloneIndex);
-     super.startDocument();
-     NodeImpl node = null ;
-      try {
-      node = (NodeImpl) this.getProperty( "http://apache.org/xml/properties/dom/current-element-node" );
-      //System.out.println( "The node = " + node );
-      }
-     catch( org.xml.sax.SAXException ex )
-      {
-        System.err.println( "except" + ex );;
-      }
-     
-//     NodeImpl node = (NodeImpl)getCurrentNode();       // Get current node
-     if( node != null )
-          node.setUserData(  String.valueOf( getLocator().getLineNumber() ) ); // Save location String into node
-  } //startDocument 
-   
-
-   public void ignorableWhitespace(int dataIndex) throws Exception
-    {
-    if(! NotIncludeIgnorableWhiteSpaces )
-       super.ignorableWhitespace( dataIndex);
-    else
-       ;// Ignore ignorable white spaces
-    }// ignorableWhitespace
-   
-
-
-   //
-   // Main
-   //
-
-   /** Main program entry point. */
-   public static void main(String argv[]) {
-      // is there anything to do?
-      if ( argv.length == 0 ) {
-         printUsage();
-         System.exit(1);
-      }
-      // check parameters
-
-      for ( int i = 0; i < argv.length; i++ ) {
-         String arg = argv[i];
-
-         // options
-         if ( arg.startsWith("-") ) {
-            if ( arg.equals("-h") ) {
-               printUsage();
-               System.exit(1);
-            }
-            if (arg.equals("-i")) {
-                   NotIncludeIgnorableWhiteSpaces = true;
-                   continue;
-               }
-            
-         }
-      // DOMAddLine parse and print
-
-      DOMAddLines domAddExample = new DOMAddLines( arg );
-      Document doc             = domAddExample.getDocument();
-      domAddExample.print( doc );
-
-     }
-   } // main(String[])
-
-   /** Prints the usage. */
-   private static void printUsage() {
-      System.err.println("usage: jre dom.DOMAddLines uri ...");
-      System.err.println();
-      System.err.println("  -h       This help screen.");
-      System.err.println("  -i       don't print ignorable white spaces");
-
-   } // printUsage()
-
-}
diff --git a/samples/dom/DOMCount.java b/samples/dom/DOMCount.java
deleted file mode 100644
index bc13652..0000000
--- a/samples/dom/DOMCount.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package dom;
-
-import util.Arguments;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-
-import org.apache.xerces.dom.TextImpl;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * A sample DOM counter. This sample program illustrates how to
- * traverse a DOM tree in order to information about the document.
- *
- * @version $id$
- */
-public class DOMCount {
-
-    //
-    // Constants
-    //
-
-    /** Default parser name. */
-    private static final String
-    DEFAULT_PARSER_NAME = "dom.wrappers.DOMParser";
-
-    private static boolean setValidation    = false; //defaults
-    private static boolean setNameSpaces    = true;
-    private static boolean setSchemaSupport = true;
-    private static boolean setDeferredDOM   = true;
-
-
-
-    //
-    // Data
-    //
-
-    /** Elements. */
-    private long elements;
-
-    /** Attributes. */
-    private long attributes;
-
-    /** Characters. */
-    private long characters;
-
-    /** Ignorable whitespace. */
-    private long ignorableWhitespace;
-
-
-    //
-    // Public static methods
-    //
-
-    /** Counts the resulting document tree. */
-    public static void count(String parserWrapperName, String uri) {
-
-        try {
-            DOMParserWrapper parser =
-            (DOMParserWrapper)Class.forName(parserWrapperName).newInstance();
-            DOMCount counter = new DOMCount();
-            long before = System.currentTimeMillis();
-            parser.setFeature( "http://apache.org/xml/features/dom/defer-node-expansion",
-
-                               setDeferredDOM );
-            parser.setFeature( "http://xml.org/sax/features/validation", 
-                               setValidation );
-            parser.setFeature( "http://xml.org/sax/features/namespaces",
-                               setNameSpaces );
-            parser.setFeature( "http://apache.org/xml/features/validation/schema",
-                               setSchemaSupport );
-
-            Document document = parser.parse(uri);
-            counter.traverse(document);
-            long after = System.currentTimeMillis();
-            counter.printResults(uri, after - before);
-        } catch (org.xml.sax.SAXParseException spe) {
-        } catch (org.xml.sax.SAXNotRecognizedException ex ){
-        } catch (org.xml.sax.SAXNotSupportedException ex ){
-        } catch (org.xml.sax.SAXException se) {
-            if (se.getException() != null)
-                se.getException().printStackTrace(System.err);
-            else
-                se.printStackTrace(System.err);
-        } catch (Exception e) {
-            e.printStackTrace(System.err);
-        }
-
-    } // print(String,String,boolean)
-
-    //
-    // Public methods
-    //
-
-    /** Traverses the specified node, recursively. */
-    public void traverse(Node node) {
-
-        // is there anything to do?
-        if (node == null) {
-            return;
-        }
-
-        int type = node.getNodeType();
-        switch (type) {
-        // print document
-        case Node.DOCUMENT_NODE: {
-                elements            = 0;
-                attributes          = 0;
-                characters          = 0;
-                ignorableWhitespace = 0;
-                traverse(((Document)node).getDocumentElement());
-                break;
-            }
-
-            // print element with attributes
-        case Node.ELEMENT_NODE: {
-                elements++;
-                NamedNodeMap attrs = node.getAttributes();
-                if (attrs != null) {
-                    attributes += attrs.getLength();
-                }
-                NodeList children = node.getChildNodes();
-                if (children != null) {
-                    int len = children.getLength();
-                    for (int i = 0; i < len; i++) {
-                        traverse(children.item(i));
-                    }
-                }
-                break;
-            }
-
-            // handle entity reference nodes
-        case Node.ENTITY_REFERENCE_NODE: {
-                NodeList children = node.getChildNodes();
-                if (children != null) {
-                    int len = children.getLength();
-                    for (int i = 0; i < len; i++) {
-                        traverse(children.item(i));
-                    }
-                }
-                break;
-            }
-
-            // print text
-        case Node.CDATA_SECTION_NODE: {
-                characters += node.getNodeValue().length();
-                break;
-            }
-        case Node.TEXT_NODE: {
-                if (node instanceof TextImpl) {
-                    if (((TextImpl)node).isIgnorableWhitespace())
-                        ignorableWhitespace += node.getNodeValue().length();
-                    else
-                        characters += node.getNodeValue().length();
-                } else
-                    characters += node.getNodeValue().length();
-                break;
-            }
-        }
-
-    } // traverse(Node)
-
-    /** Prints the results. */
-    public void printResults(String uri, long time) {
-
-        // filename.xml: 631 ms (4 elems, 0 attrs, 78 spaces, 0 chars)
-        System.out.print(uri);
-        System.out.print(": ");
-        System.out.print(time);
-        System.out.print(" ms (");
-        System.out.print(elements);
-        System.out.print(" elems, ");
-        System.out.print(attributes);
-        System.out.print(" attrs, ");
-        System.out.print(ignorableWhitespace);
-        System.out.print(" spaces, ");
-        System.out.print(characters);
-        System.out.print(" chars)");
-        System.out.println();
-
-    } // printResults(String,long)
-
-    //
-    // Main
-    //
-
-    /** Main program entry point. */
-    public static void main(String argv[]) {
-
-        Arguments argopt = new Arguments();
-        argopt.setUsage( new String[] {
-                             "usage: java dom.DOMCount (options) uri ...",
-                             "",
-                             "options:",
-                             "  -p name  Specify DOM parser wrapper by name.",
-                             "  -n | -N  Turn on/off namespace [default=on]",
-                             "  -v | -V  Turn on/off validation [default=off]",
-                             "  -s | -S  Turn on/off Schema support [default=on]",
-                             "  -d | -D  Turn on/off deferred DOM [default=on]",
-                             "  -h       This help screen."} );
-
-
-        // is there anything to do?
-        if (argv.length == 0) {
-            argopt.printUsage();
-            System.exit(1);
-        }
-
-        // vars
-        String  parserName = DEFAULT_PARSER_NAME;
-
-        argopt.parseArgumentTokens(argv , new char[] { 'p'} );
-
-        int   c;
-        String arg = null; 
-        while ( ( arg =  argopt.getlistFiles() ) != null ) {
-outer:
-            while ( (c =  argopt.getArguments()) != -1 ){
-                switch (c) {
-                case 'v':
-                    setValidation = true;
-                    //System.out.println( "v" );
-                    break;
-                case 'V':
-                    setValidation = false;
-                    //System.out.println( "V" );
-                    break;
-                case 'N':
-                    setNameSpaces = false;
-                    break;
-                case 'n':
-                    setNameSpaces = true;
-                    break;
-                case 'p':
-                    //System.out.println('p');
-                    parserName = argopt.getStringParameter();
-                    //System.out.println( "parserName = " + parserName );
-                    break;
-                case 'd':
-                    setDeferredDOM = true;
-                    break;
-                case 'D':
-                    setDeferredDOM = false;
-                    break;
-                case 's':
-                    //System.out.println("s" );
-                    setSchemaSupport = true;
-                    break;
-                case 'S':
-                    //System.out.println("S" );
-                    setSchemaSupport = false;
-                    break;
-                case '?':
-                case 'h':
-                case '-':
-                    argopt.printUsage();
-                    System.exit(1);
-                    break;
-                case  -1:
-                    //System.out.println( "-1" );
-                    break outer;
-                default:
-                    
-                    break;
-                }
-            }
-
-            count(parserName, arg ); //count uri
-        }
-
-    } // main(String[])
-
-} // class DOMCount
diff --git a/samples/dom/DOMFilter.java b/samples/dom/DOMFilter.java
deleted file mode 100644
index c6fe43c..0000000
--- a/samples/dom/DOMFilter.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package dom;                    
-
-import util.Arguments;
-
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-
-/**
- * A sample DOM filter. This sample program illustrates how to
- * use the Document#getElementsByTagName() method to quickly 
- * and easily locate elements by name.
- *
- * @version $Id$
- */
-public class DOMFilter {
-
-    //
-    // Constants
-    //
-
-    /** Default parser name. */
-    private static final String 
-    DEFAULT_PARSER_NAME = "dom.wrappers.DOMParser";
-
-    private static boolean setValidation    = false; //defaults
-    private static boolean setNameSpaces    = true;
-    private static boolean setSchemaSupport = true;
-    private static boolean setDeferredDOM   = true;
-
-
-
-    //
-    // Public static methods
-    //
-
-    /** Prints the specified elements in the given document. */
-    public static void print(String parserWrapperName, String uri, 
-                             String elementName, String attributeName) {
-
-        try {
-            // parse document
-            DOMParserWrapper parser = 
-            (DOMParserWrapper)Class.forName(parserWrapperName).newInstance();
-
-            parser.setFeature( "http://apache.org/xml/features/dom/defer-node-expansion",
-                               setDeferredDOM );
-            parser.setFeature( "http://xml.org/sax/features/validation", 
-                               setValidation );
-            parser.setFeature( "http://xml.org/sax/features/namespaces",
-                               setNameSpaces );
-            parser.setFeature( "http://apache.org/xml/features/validation/schema",
-                               setSchemaSupport );
-
-
-            Document document = parser.parse(uri);
-
-            // get elements that match
-            NodeList elements = document.getElementsByTagName(elementName);
-
-            // print nodes
-            print(elements, attributeName);
-        } catch (Exception e) {
-            e.printStackTrace(System.err);
-        }
-
-    } // print(String,String,String,String)
-
-    //
-    // Private static methods
-    //
-
-    /** 
-     * Prints the contents of the given element node list. If the given
-     * attribute name is non-null, then all of the elements are printed 
-     * out
-     */
-    private static void print(NodeList elements, String attributeName) {
-
-        // is there anything to do?
-        if (elements == null) {
-            return;
-        }
-
-        // print all elements
-        if (attributeName == null) {
-            int elementCount = elements.getLength();
-            for (int i = 0; i < elementCount; i++) {
-                Element element = (Element)elements.item(i);
-                print(element, element.getAttributes());
-            }
-        }
-
-        // print elements with given attribute name
-        else {
-            int elementCount = elements.getLength();
-            for (int i = 0; i < elementCount; i++) {
-                Element      element    = (Element)elements.item(i);
-                NamedNodeMap attributes = element.getAttributes();
-                if (attributes.getNamedItem(attributeName) != null) {
-                    print(element, attributes);
-                }
-            }
-        }
-
-    } // print(NodeList,String)
-
-    /** Prints the specified element. */
-    private static void print(Element element, NamedNodeMap attributes) {
-
-        System.out.print('<');
-        System.out.print(element.getNodeName());
-        if (attributes != null) {
-            int attributeCount = attributes.getLength();
-            for (int i = 0; i < attributeCount; i++) {
-                Attr attribute = (Attr)attributes.item(i);
-                System.out.print(' ');
-                System.out.print(attribute.getNodeName());
-                System.out.print("=\"");
-                System.out.print(normalize(attribute.getNodeValue()));
-                System.out.print('"');
-            }
-        }
-        System.out.println('>');
-
-    } // print(Element,NamedNodeMap)
-
-    /** Normalizes the given string. */
-    private static String normalize(String s) {
-        StringBuffer str = new StringBuffer();
-
-        int len = (s != null) ? s.length() : 0;
-        for (int i = 0; i < len; i++) {
-            char ch = s.charAt(i);
-            switch (ch) {
-            case '<': {
-                    str.append("&lt;");
-                    break;
-                }
-            case '>': {
-                    str.append("&gt;");
-                    break;
-                }
-            case '&': {
-                    str.append("&amp;");
-                    break;
-                }
-            case '"': {
-                    str.append("&quot;");
-                    break;
-                }
-            case '\r':
-            case '\n': {
-                    str.append("&#");
-                    str.append(Integer.toString(ch));
-                    str.append(';');
-                    break;
-                }
-            default: {
-                    str.append(ch);
-                }
-            }
-        }
-
-        return str.toString();
-
-    } // normalize(String):String
-
-    //
-    // Main
-    //
-
-    /** Main program entry point. */
-    public static void main(String argv[]) {
-
-        Arguments argopt = new Arguments();
-        argopt.setUsage( new String[] 
-                         { "usage: java dom.DOMFilter (options) uri ...","",
-                             "options:",
-                             "  -p name  Specify DOM parser wrapper by name.",
-                             "  -e name  Specify element name to search for. Default is \"*\".",
-                             "  -a name  Specify attribute name of specified elements.",
-                             "  -p name  Specify DOM parser wrapper by name.",
-                             "  -n | -N  Turn on/off namespace [default=on]",
-                             "  -v | -V  Turn on/off validation [default=on]",
-                             "  -s | -S  Turn on/off Schema support [default=on]",
-                             "  -d | -D  Turn on/off deferred DOM [default=on]",
-                             "  -h       This help screen."} );
-
-        // is there anything to do?
-        if (argv.length == 0) {
-            argopt.printUsage();
-            System.exit(1);
-        }
-
-        // vars
-        String parserName    = DEFAULT_PARSER_NAME;
-        String elementName   = "*"; // all elements
-        String attributeName = null;
-
-
-        /////
-
-        argopt.parseArgumentTokens(argv , new char[] { 'p', 'e', 'a'} );
-        int   c;
-        String arg = null; 
-        while ( ( arg =  argopt.getlistFiles() ) != null ) {
-outer:
-            while ( (c =  argopt.getArguments()) != -1 ){
-                switch (c) {
-                case 'v':
-                    setValidation = true;
-                    break;
-                case 'V':
-                    setValidation = false;
-                    break;
-                case 'N':
-                    setNameSpaces = false;
-                    break;
-                case 'n':
-                    setNameSpaces = true;
-                    break;
-                case 'p':
-                    parserName = argopt.getStringParameter();
-                    break;
-                case 'd':
-                    setDeferredDOM = true;
-                    break;
-                case 'D':
-                    setDeferredDOM = false;
-                    break;
-                case 's':
-                    setSchemaSupport = true;
-                    break;
-                case 'S':
-                    setSchemaSupport = false;
-                    break;
-                case 'e':
-                    elementName = argopt.getStringParameter();
-                    break;
-                case 'a':
-                    attributeName  = argopt.getStringParameter();
-                    break;
-                case '?':
-                case 'h':
-                case '-':
-                    argopt.printUsage();
-                    System.exit(1);
-                    break;
-                case -1:
-                    break outer;
-                default:
-                    break;
-                }
-            }
-            // print uri
-            System.err.println(arg+':');
-            print(parserName, arg, elementName, attributeName);
-        }
-    } // main(String[])
-
-} // class DOMFilter
-
diff --git a/samples/dom/DOMGenerate.java b/samples/dom/DOMGenerate.java
deleted file mode 100644
index ece4162..0000000
--- a/samples/dom/DOMGenerate.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-
-package dom;
-import  org.w3c.dom.*;
-import  org.apache.xerces.dom.DocumentImpl;
-import  org.apache.xerces.dom.DOMImplementationImpl;
-import  org.w3c.dom.Document;
-import  org.apache.xml.serialize.OutputFormat;
-import  org.apache.xml.serialize.Serializer;
-import  org.apache.xml.serialize.SerializerFactory;
-import  org.apache.xml.serialize.XMLSerializer;
-import  java.io.*;
-
-/**
- * Simple Sample that:
- * - Generate a DOM from Scratch.
- * - Output DOM to a String using Serializer
- * @author Jeffrey Rodriguez
- * @version $id$
- */
-public class DOMGenerate {
-    public static void main( String[] argv ) {
-        try {
-            Document doc= new DocumentImpl();
-            Element root = doc.createElement("person");     // Create Root Element
-            Element item = doc.createElement("name");       // Create element
-            item.appendChild( doc.createTextNode("Jeff") );
-            root.appendChild( item );                       // atach element to Root element
-            item = doc.createElement("age");                // Create another Element
-            item.appendChild( doc.createTextNode("28" ) );       
-            root.appendChild( item );                       // Attach Element to previous element down tree
-            item = doc.createElement("height");            
-            item.appendChild( doc.createTextNode("1.80" ) );
-            root.appendChild( item );                       // Attach another Element - grandaugther
-            doc.appendChild( root );                        // Add Root to Document
-
-
-            OutputFormat    format  = new OutputFormat( doc );   //Serialize DOM
-            StringWriter  stringOut = new StringWriter();        //Writer will be a String
-            XMLSerializer    serial = new XMLSerializer( stringOut, format );
-            serial.asDOMSerializer();                            // As a DOM Serializer
-
-            serial.serialize( doc.getDocumentElement() );
-
-            System.out.println( "STRXML = " + stringOut.toString() ); //Spit out DOM as a String
-        } catch ( Exception ex ) {
-            ex.printStackTrace();
-        }
-    }
-}
-
diff --git a/samples/dom/DOMParserWrapper.java b/samples/dom/DOMParserWrapper.java
deleted file mode 100644
index 331c369..0000000
--- a/samples/dom/DOMParserWrapper.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package dom;
-
-import org.w3c.dom.Document;
-
-/**
- * Encapsulates a DOM parser.
- *
- * @version $id$
- */
-
-import org.xml.sax.SAXNotRecognizedException;
-import org.xml.sax.SAXNotSupportedException;
-
-public interface DOMParserWrapper {
-
-    //
-    // DOMParserWrapper methods
-    //
-
-    /** Parses the specified URI and returns the document. */
-    public Document parse(String uri) throws Exception;
-
-  /**
-   * Set the state of a feature.
-   *
-   * Set the state of any feature in a SAX2 parser.  The parser
-   * might not recognize the feature, and if it does recognize
-   * it, it might not be able to fulfill the request.
-   *
-   * @param featureId The unique identifier (URI) of the feature.
-   * @param state The requested state of the feature (true or false).
-   *
-   * @exception org.xml.sax.SAXNotRecognizedException If the
-   *            requested feature is not known.
-   * @exception org.xml.sax.SAXNotSupportedException If the
-   *            requested feature is known, but the requested
-   *            state is not supported.
-   * @exception org.xml.sax.SAXException If there is any other
-   *            problem fulfilling the request.
-   */
-
-    public void     setFeature(String featureId, boolean state)
-            throws  SAXNotRecognizedException, SAXNotSupportedException; 
-
-} // interface DOMParserWrapper
diff --git a/samples/dom/DOMWriter.java b/samples/dom/DOMWriter.java
deleted file mode 100644
index 394c2fb..0000000
--- a/samples/dom/DOMWriter.java
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package dom;
-
-import util.Arguments;
-
-
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.apache.xerces.readers.MIME2Java;
-
-
-/**
- * A sample DOM writer. This sample program illustrates how to
- * traverse a DOM tree in order to print a document that is parsed.
- *
- * @version $Id$
- */
-public class DOMWriter {
-
-    //
-    // Constants
-    //
-
-
-    /** Default parser name. */
-    private static final String 
-    DEFAULT_PARSER_NAME = "dom.wrappers.DOMParser";
-
-
-    private static boolean setValidation    = false; //defaults
-    private static boolean setNameSpaces    = true;
-    private static boolean setSchemaSupport = true;
-    private static boolean setDeferredDOM   = true;
-
-
-
-    //
-    // Data
-    //
-
-    /** Default Encoding */
-    private static  String
-    PRINTWRITER_ENCODING = "UTF8";
-
-    private static String MIME2JAVA_ENCODINGS[] =
-    { "Default", "UTF-8", "US-ASCII", "ISO-8859-1", "ISO-8859-2", "ISO-8859-3", "ISO-8859-4", 
-        "ISO-8859-5", "ISO-8859-6", "ISO-8859-7", "ISO-8859-8", "ISO-8859-9", "ISO-2022-JP",
-        "SHIFT_JIS", "EUC-JP","GB2312", "BIG5", "EUC-KR", "ISO-2022-KR", "KOI8-R", "EBCDIC-CP-US", 
-        "EBCDIC-CP-CA", "EBCDIC-CP-NL", "EBCDIC-CP-DK", "EBCDIC-CP-NO", "EBCDIC-CP-FI", "EBCDIC-CP-SE",
-        "EBCDIC-CP-IT", "EBCDIC-CP-ES", "EBCDIC-CP-GB", "EBCDIC-CP-FR", "EBCDIC-CP-AR1", 
-        "EBCDIC-CP-HE", "EBCDIC-CP-CH", "EBCDIC-CP-ROECE","EBCDIC-CP-YU",  
-        "EBCDIC-CP-IS", "EBCDIC-CP-AR2", "UTF-16"
-    };
-
-
-/*
-   private static String JAVA_SUPPORTED_ENCODINGS[] = 
-   { "Default", "8859_1", "8859_2", "8859_3", "8859_4", "8859_5", "8859_6", 
-      "8859_7", "8859_8", "8859_9", "Cp037", "Cp273", "Cp277", "Cp278",
-      "Cp280", "Cp284", "Cp285", "Cp297", "Cp420", "Cp424", "Cp437",
-      "Cp500", "Cp737", "Cp775", "Cp838", "Cp850", "Cp852", "Cp855", "Cp856",
-      "Cp857", "Cp860", "Cp861",
-      "Cp862", "Cp863", "Cp864", "Cp865", "Cp866", "Cp868", "Cp869", "Cp870",
-      "Cp871", "Cp874", "Cp875",
-      "Cp918", "Cp921", "Cp922", "Cp930", "Cp933", "Cp935", "Cp937", "Cp939",
-      "Cp942", "Cp948", "Cp949",
-      "Cp950", "Cp964", "Cp970", "Cp1006", "Cp1025", "Cp1026", "Cp1046", 
-      "Cp1097", "Cp1098", "Cp1112",
-      "Cp1122", "Cp1123", "Cp1124", "Cp1250", "Cp1251", "Cp1252", "Cp1253",
-      "Cp1254", "Cp1255", "Cp1256",
-      "Cp1257", "Cp1258", "Cp1381", "Cp1383", "Cp33722", "MS874",
-      "EUCJIS", "GB2312", 
-       "GBK", "ISO2022CN_CNS", "ISO2022CN_GB",
-      "JIS",
-      "JIS0208", "KOI8_R", "KSC5601","MS874",
-      "SJIS",  "Big5", "CNS11643",
-      "MacArabic", "MacCentralEurope", "MacCroatian", "MacCyrillic",
-      "MacDingbat", "MacGreek",
-      "MacHebrew", "MacIceland", "MacRoman", "MacRomania", "MacSymbol",
-      "MacThai", "MacTurkish",
-      "MacUkraine", "SJIS", "Unicode", "UnicodeBig", "UnicodeLittle", "UTF8"};
-*/
-
-    /** Print writer. */
-    protected PrintWriter out;
-
-    /** Canonical output. */
-    protected boolean canonical;
-
-
-    public DOMWriter(String encoding, boolean canonical)              
-    throws UnsupportedEncodingException {
-        out = new PrintWriter(new OutputStreamWriter(System.out, encoding));
-        this.canonical = canonical;
-    } // <init>(String,boolean)
-
-    //
-    // Constructors
-    //
-
-    /** Default constructor. */
-    public DOMWriter(boolean canonical) throws UnsupportedEncodingException {
-        this( getWriterEncoding(), canonical);
-    }
-
-    public static String getWriterEncoding( ) {
-        return(PRINTWRITER_ENCODING);
-    }// getWriterEncoding 
-
-    public static void  setWriterEncoding( String encoding ) {
-        if ( encoding.equalsIgnoreCase( "DEFAULT" ) )
-            PRINTWRITER_ENCODING  = "UTF8";
-        else if ( encoding.equalsIgnoreCase( "UTF-16" ) )
-            PRINTWRITER_ENCODING  = "Unicode";
-        else
-            PRINTWRITER_ENCODING = MIME2Java.convert( encoding ); 
-    }// setWriterEncoding 
-
-
-    public static boolean isValidJavaEncoding( String encoding ) {
-        for ( int i = 0; i < MIME2JAVA_ENCODINGS.length; i++ )
-            if ( encoding.equals( MIME2JAVA_ENCODINGS[i] ) )
-                return(true);
-
-        return(false);
-    }// isValidJavaEncoding 
-
-
-
-    /** Prints the resulting document tree. */
-    public static void print(String parserWrapperName, String uri, 
-                             boolean canonical ) {
-        try {
-            DOMParserWrapper parser = 
-            (DOMParserWrapper)Class.forName(parserWrapperName).newInstance();
-
-            parser.setFeature( "http://apache.org/xml/features/dom/defer-node-expansion",
-                               setDeferredDOM );
-            parser.setFeature( "http://xml.org/sax/features/validation", 
-                               setValidation );
-            parser.setFeature( "http://xml.org/sax/features/namespaces",
-                               setNameSpaces );
-            parser.setFeature( "http://apache.org/xml/features/validation/schema",
-                               setSchemaSupport );
-
-            Document document = parser.parse(uri);
-            DOMWriter writer = new DOMWriter(canonical);
-            writer.print(document);
-        } catch ( Exception e ) {
-            //e.printStackTrace(System.err);
-        }
-
-    } // print(String,String,boolean)
-
-
-    /** Prints the specified node, recursively. */
-    public void print(Node node) {
-
-        // is there anything to do?
-        if ( node == null ) {
-            return;
-        }
-
-        int type = node.getNodeType();
-        switch ( type ) {
-        // print document
-        case Node.DOCUMENT_NODE: {
-                if ( !canonical ) {
-                    String  Encoding = this.getWriterEncoding();
-                    if ( Encoding.equalsIgnoreCase( "DEFAULT" ) )
-                        Encoding = "UTF-8";
-                    else if ( Encoding.equalsIgnoreCase( "Unicode" ) )
-                        Encoding = "UTF-16";
-                    else
-                        Encoding = MIME2Java.reverse( Encoding );
-
-                    out.println("<?xml version=\"1.0\" encoding=\""+
-                                Encoding + "\"?>");
-                }
-                print(((Document)node).getDocumentElement());
-                out.flush();
-                break;
-            }
-
-            // print element with attributes
-        case Node.ELEMENT_NODE: {
-                out.print('<');
-                out.print(node.getNodeName());
-                Attr attrs[] = sortAttributes(node.getAttributes());
-                for ( int i = 0; i < attrs.length; i++ ) {
-                    Attr attr = attrs[i];
-                    out.print(' ');
-                    out.print(attr.getNodeName());
-                    out.print("=\"");
-                    out.print(normalize(attr.getNodeValue()));
-                    out.print('"');
-                }
-                out.print('>');
-                NodeList children = node.getChildNodes();
-                if ( children != null ) {
-                    int len = children.getLength();
-                    for ( int i = 0; i < len; i++ ) {
-                        print(children.item(i));
-                    }
-                }
-                break;
-            }
-
-            // handle entity reference nodes
-        case Node.ENTITY_REFERENCE_NODE: {
-                if ( canonical ) {
-                    NodeList children = node.getChildNodes();
-                    if ( children != null ) {
-                        int len = children.getLength();
-                        for ( int i = 0; i < len; i++ ) {
-                            print(children.item(i));
-                        }
-                    }
-                } else {
-                    out.print('&');
-                    out.print(node.getNodeName());
-                    out.print(';');
-                }
-                break;
-            }
-
-            // print cdata sections
-        case Node.CDATA_SECTION_NODE: {
-                if ( canonical ) {
-                    out.print(normalize(node.getNodeValue()));
-                } else {
-                    out.print("<![CDATA[");
-                    out.print(node.getNodeValue());
-                    out.print("]]>");
-                }
-                break;
-            }
-
-            // print text
-        case Node.TEXT_NODE: {
-                out.print(normalize(node.getNodeValue()));
-                break;
-            }
-
-            // print processing instruction
-        case Node.PROCESSING_INSTRUCTION_NODE: {
-                out.print("<?");
-                out.print(node.getNodeName());
-                String data = node.getNodeValue();
-                if ( data != null && data.length() > 0 ) {
-                    out.print(' ');
-                    out.print(data);
-                }
-                out.print("?>");
-                break;
-            }
-        }
-
-        if ( type == Node.ELEMENT_NODE ) {
-            out.print("</");
-            out.print(node.getNodeName());
-            out.print('>');
-        }
-
-        out.flush();
-
-    } // print(Node)
-
-    /** Returns a sorted list of attributes. */
-    protected Attr[] sortAttributes(NamedNodeMap attrs) {
-
-        int len = (attrs != null) ? attrs.getLength() : 0;
-        Attr array[] = new Attr[len];
-        for ( int i = 0; i < len; i++ ) {
-            array[i] = (Attr)attrs.item(i);
-        }
-        for ( int i = 0; i < len - 1; i++ ) {
-            String name  = array[i].getNodeName();
-            int    index = i;
-            for ( int j = i + 1; j < len; j++ ) {
-                String curName = array[j].getNodeName();
-                if ( curName.compareTo(name) < 0 ) {
-                    name  = curName;
-                    index = j;
-                }
-            }
-            if ( index != i ) {
-                Attr temp    = array[i];
-                array[i]     = array[index];
-                array[index] = temp;
-            }
-        }
-
-        return(array);
-
-    } // sortAttributes(NamedNodeMap):Attr[]
-
-
-    //
-    // Main
-    //
-
-    /** Main program entry point. */
-    public static void main(String argv[]) {
-        Arguments argopt = new Arguments();
-        argopt.setUsage( new String[] {
-                             "usage: java dom.DOMWriter (options) uri ...","",
-                             "options:",
-                             "  -n | -N  Turn on/off namespace [default=on]",
-                             "  -v | -V  Turn on/off validation [default=off]",
-                             "  -s | -S  Turn on/off Schema support [default=on]",
-                             "  -d | -D  Turn on/off deferred DOM [default=on]",
-                             "  -c       Canonical XML output.",
-                             "  -h       This help screen.",
-                             "  -e       Output Java Encoding.",
-                             "           Default encoding: UTF-8"} );
-
-
-
-        // is there anything to do?
-        if ( argv.length == 0 ) {
-            argopt.printUsage();
-            System.exit(1);
-        }
-
-        // vars
-        String  parserName = DEFAULT_PARSER_NAME;
-        boolean canonical  = false;
-        String  encoding   = "UTF8"; // default encoding
-
-        argopt.parseArgumentTokens(argv, new char[] { 'p', 'e'} );
-
-        int   c;
-        String arg = null; 
-        while ( ( arg =  argopt.getlistFiles() ) != null ) {
-
-            outer:
-            while ( (c =  argopt.getArguments()) != -1 ){
-                switch (c) {
-                case 'c':
-                    canonical = true;
-                    break;
-                case 'e':
-                    encoding      = argopt.getStringParameter();
-                    if ( encoding != null && isValidJavaEncoding( encoding ) )
-                        setWriterEncoding( encoding );
-                    else {
-                        printValidJavaEncoding();
-                        System.exit( 1 );
-                    }
-                    break;
-                case 'v':
-                    setValidation = true;
-                    break;
-                case 'V':
-                    setValidation = false;
-                    break;
-                case 'N':
-                    setNameSpaces = false;
-                    break;
-                case 'n':
-                    setNameSpaces = true;
-                    break;
-                case 'p':
-                    parserName    = argopt.getStringParameter();
-                    break;
-                case 'd':
-                    setDeferredDOM = true;
-                    break;
-                case 'D':
-                    setDeferredDOM = false;
-                    break;
-                case 's':
-                    setSchemaSupport = true;
-                    break;
-                case 'S':
-                    setSchemaSupport = false;
-                    break;
-                case '?':
-                case 'h':
-                case '-':
-                    argopt.printUsage();
-                    System.exit(1);
-                    break;
-                case -1:
-                    break outer;
-                default:
-                    break;
-                }
-            }
-            // print uri
-             // print uri
-            System.err.println(arg+':');
-            print(parserName, arg, canonical );
-            System.err.println();
-        }
-    } // main(String[])
-
-
-    /** Normalizes the given string. */
-    protected String normalize(String s) {
-        StringBuffer str = new StringBuffer();
-
-        int len = (s != null) ? s.length() : 0;
-        for ( int i = 0; i < len; i++ ) {
-            char ch = s.charAt(i);
-            switch ( ch ) {
-            case '<': {
-                    str.append("&lt;");
-                    break;
-                }
-            case '>': {
-                    str.append("&gt;");
-                    break;
-                }
-            case '&': {
-                    str.append("&amp;");
-                    break;
-                }
-            case '"': {
-                    str.append("&quot;");
-                    break;
-                }
-            case '\r':
-            case '\n': {
-                    if ( canonical ) {
-                        str.append("&#");
-                        str.append(Integer.toString(ch));
-                        str.append(';');
-                        break;
-                    }
-                    // else, default append char
-                }
-            default: {
-                    str.append(ch);
-                }
-            }
-        }
-
-        return(str.toString());
-
-    } // normalize(String):String
-
-
-    private static void printValidJavaEncoding() {
-        System.err.println( "    ENCODINGS:" );
-        System.err.print( "   " );
-        for ( int i = 0;
-            i < MIME2JAVA_ENCODINGS.length; i++) {
-            System.err.print( MIME2JAVA_ENCODINGS[i] + " " );
-            if ( (i % 7 ) == 0 ){
-                System.err.println();
-                System.err.print( "   " );
-            }
-        }
-
-    } // printJavaEncoding()            
-
-} 
diff --git a/samples/dom/Makefile b/samples/dom/Makefile
deleted file mode 100644
index 9fb1818..0000000
--- a/samples/dom/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# Makefile for directory ./dom
-
-TARGETS=\
-	DOMAddLines.class\
-	DOMCount.class\
-	DOMFilter.class\
-	DOMGenerate.class\
-	DOMParserWrapper.class\
-	DOMWriter.class
-
-DIRS = traversal wrappers
-
-TOP = ../..
-include $(TOP)/src/Makefile.incl
diff --git a/samples/dom/traversal/IteratorView.java b/samples/dom/traversal/IteratorView.java
deleted file mode 100644
index 1f1521b..0000000
--- a/samples/dom/traversal/IteratorView.java
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package dom.traversal;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.Hashtable;
-import java.util.Enumeration;
-import javax.swing.*;
-import javax.swing.tree.*;
-import javax.swing.event.*;
-import org.apache.xerces.parsers.*;
-import org.w3c.dom.*;
-import org.w3c.dom.traversal.*;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-import ui.DOMTreeFull;
-
-/** This class shows a DOM Document in a JTree, and presents controls
- *  which allow the user to create and view the progress of a NodeIterator
- *  in the DOM tree.
- */
-public class IteratorView 
-    extends JFrame 
-    implements ActionListener {
-
-    Document document;
-    TreeNode lastSelected;
-    DOMParser parser;
-    JTextArea messageText;
-    JScrollPane messageScroll;
-    DOMTreeFull jtree;
-    NodeIterator iterator;
-    NameNodeFilter nameNodeFilter;
-    
-    JButton nextButton;
-    JButton prevButton;
-    JButton removeButton;
-    JButton addButton;
-    JTextField addText;
-    JButton newIterator;
-    JList whatToShow;
-    JCheckBox match;
-    JTextField nameFilter;
-    String whatArray[] = new String [] { 
-            "ALL",
-            "ELEMENT",
-            "ATTRIBUTE",
-            "TEXT",
-            "CDATA_SECTION",
-            "ENTITY_REFERENCE",
-            "ENTITY",
-            "PROCESSING_INSTRUCTION", 
-            "COMMENT", 
-            "DOCUMENT", 
-            "DOCUMENT_TYPE",
-            "DOCUMENT_FRAGMENT",
-            "NOTATION" 
-            };
-    JCheckBox expandERs;
-    
-    Hashtable treeNodeMap = new Hashtable();
-    
-    
-    /** main */
-    public static void main (String args[]) {
-
-        if (args.length > 0) {
-            String filename = args[0];
-            try {
-                IteratorView frame = new IteratorView(filename) ;
-                frame.addWindowListener(new java.awt.event.WindowAdapter() {
-                 public void windowClosing(java.awt.event.WindowEvent e) {
-                     System.exit(0);
-                 }
-                });
-                frame.setSize(640, 480);
-                frame.setVisible(true);
-                } catch (Exception e) {
-                    e.printStackTrace(System.err);
-                }
-        }
-    }
-    
-    /** Constructor */
-    public IteratorView (String filename) {
-        super("IteratorView: "+filename);
-        try {
-            parser = new DOMParser();
-            parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", true);
-            parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
-            Errors errors = new Errors();
-            parser.setErrorHandler(errors);
-            parser.parse(filename);
-            document = parser.getDocument();
-            
-            if (!document.supports("Traversal", "2.0")) {
-                // This cannot happen with ou DOMParser...
-                throw new RuntimeException("This DOM Document does not support Traversal");
-            }
-
-            // jtree  UI setup
-            jtree = new DOMTreeFull((Node)document);
-            jtree.getSelectionModel().setSelectionMode
-                (TreeSelectionModel.SINGLE_TREE_SELECTION);
-            jtree.setRootVisible(false);
-
-            // Listen for when the selection changes, call nodeSelected(node)
-            jtree.addTreeSelectionListener(
-                new TreeSelectionListener() {
-                    public void valueChanged(TreeSelectionEvent e) {
-                        TreePath path = (TreePath)e.getPath(); 
-                        TreeNode treeNode = (TreeNode)path.getLastPathComponent();
-                        if(jtree.getSelectionModel().isPathSelected(path))
-                                nodeSelected(treeNode);
-                    }
-                }
-            );
-            
-            
-            //expandTree();
-            
-                        
-            // controls
-            
-            //iterate panel
-            JPanel iteratePanel = new JPanel();
-            iteratePanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("Iterate"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-            
-            prevButton = new JButton("Previous");
-            iteratePanel.add(prevButton);
-            prevButton.addActionListener(this);
-            
-            nextButton = new JButton("Next");
-            iteratePanel.add(nextButton);
-            nextButton.addActionListener(this);
-        
-            //DOM tree panel
-            JPanel domPanel = new JPanel();
-            domPanel.setLayout(new BorderLayout());
-            domPanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("Selected Node"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-            
-            removeButton = new JButton("Remove Selected Node");
-            domPanel.add(removeButton, BorderLayout.NORTH);
-            removeButton.addActionListener(this);
-            
-            addButton = new JButton("Add Text Node");
-            addText = new JTextField(10);
-            domPanel.add(addButton, BorderLayout.CENTER);
-            domPanel.add(addText, BorderLayout.SOUTH);
-            addButton.addActionListener(this);
-         
-            // iterator settings
-            JPanel settingsPanel = new JPanel();
-            settingsPanel.setLayout(new BorderLayout());
-            settingsPanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("Iterator Settings"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-            JPanel iteratorPanel = new JPanel();
-            newIterator = new JButton("createNodeIterator");
-            expandERs = new JCheckBox("expandEntityReferences");
-            iteratorPanel.add(newIterator);
-            expandERs.setSelected(true);
-            iteratorPanel.add(expandERs);
-            settingsPanel.add(iteratorPanel, BorderLayout.NORTH);
-            newIterator.addActionListener(this);
-    
-            JPanel whatPanel = new JPanel();
-            whatPanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("whatToShow"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-            whatToShow = new JList(DOMTreeFull.whatArray);
-            JScrollPane whatScroll = 
-            new JScrollPane(whatToShow) {
-                    public Dimension getPreferredSize(){
-                        return new Dimension(200, 75 );
-                    }
-                };
-            
-            whatPanel.add(whatScroll);
-            
-            
-            JPanel filterPanel = new JPanel();
-            filterPanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("NodeNameFilter"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-            filterPanel.setLayout(new BorderLayout());
-            match = new JCheckBox("match/ignore node name", true);
-            nameFilter = new JTextField(10);
-            filterPanel.add(match, BorderLayout.NORTH);
-            filterPanel.add(nameFilter, BorderLayout.SOUTH);
-            
-            settingsPanel.add(whatPanel, BorderLayout.WEST);
-            settingsPanel.add(filterPanel, BorderLayout.EAST);
-            
-
-            // Listen for when the selection changes, call nodeSelected(node)
-            whatToShow.addListSelectionListener(
-                new ListSelectionListener() {
-                    public void valueChanged(ListSelectionEvent e) {
-                        // do nothing on selection...
-                    }
-                }
-            );
-            
-            
-            JPanel controlsPanel = new JPanel(new BorderLayout());
-            JPanel buttonsPanel = new JPanel(new BorderLayout());
-            buttonsPanel.add(iteratePanel, BorderLayout.NORTH);
-            buttonsPanel.add(domPanel, BorderLayout.SOUTH);
-            controlsPanel.add(buttonsPanel, BorderLayout.WEST);
-            controlsPanel.add(settingsPanel, BorderLayout.CENTER);
-            
-            controlsPanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("Controls"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-                
-                
-            // tree panel    
-            JPanel treePanel = new JPanel(new BorderLayout());
-                
-            JScrollPane treeScroll = new JScrollPane(jtree) ;
-            treeScroll.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("Tree View"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-
-            // message text UI setup
-            messageText = new JTextArea(3,5);
-
-            JPanel messagePanel = new JPanel(new BorderLayout());
-            messageScroll = new JScrollPane(messageText);
-            messagePanel.add(messageScroll);
-            messagePanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("Messages"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-            
-            JPanel mainPanel = new JPanel();
-            mainPanel.setLayout(new BorderLayout());
-            mainPanel.add(controlsPanel, BorderLayout.NORTH);
-            mainPanel.add(treeScroll, BorderLayout.CENTER);
-            mainPanel.add(messagePanel, BorderLayout.SOUTH);
-            getContentPane().add(mainPanel);
-            
-            Hashtable errorNodes = errors.getErrorNodes();
-            Enumeration elements = errorNodes.elements();
-            while (elements.hasMoreElements()) {
-                //*** append errors to messageText
-                messageText.append( (String)elements.nextElement());
-            }    
-            
-            // This cast must work, because we have tested above
-            // with document.supports("Traversal")
-            iterator = ((DocumentTraversal)document).
-                createNodeIterator(
-                    document, 
-                    NodeFilter.SHOW_ALL, 
-                    new NameNodeFilter(),
-                    true);
-            
-        } catch (Exception e) {
-            e.printStackTrace(System.err);
-        }
-    }
-    
-    public void actionPerformed(ActionEvent e) {
-        
-        if (e.getSource() == newIterator) {
-            Node node = document;
-            
-            // whatToShow section
-            int  [] indices = whatToShow.getSelectedIndices();
-            int mask = 0x0;
-            for (int i = 0; i < indices.length; i++) {
-                if (indices[i] == 0) {
-                    mask = 0xFFFF;
-                    break;
-                } else {
-                    mask = mask | 1<<indices[i]-1;
-                }
-            }
-            // filter section
-            String nameText = nameFilter.getText();
-            boolean matched = match.isSelected();
-            if (nameNodeFilter==null) {
-                nameNodeFilter = new NameNodeFilter();
-            }
-            if (nameText.equals("")) {
-                setMessage("NodeNameFilter name is \"\". Assuming null.");
-                nameText = null;
-            }
-            nameNodeFilter.setName(nameText);
-            nameNodeFilter.setMatch(matched);
-            
-            if (iterator !=null) iterator.detach();
-            boolean expand = expandERs.isSelected();
-            iterator = ((DocumentTraversal)document).
-                createNodeIterator(
-                    node, 
-                    (short)mask, 
-                    nameNodeFilter,
-                    expand);
-            setMessage("doc.createNodeIterator("+ 
-                        " root="+node+
-                        ", whatToShow="+mask+
-                        ", match="+matched+
-                        ", name="+nameText+")"
-                        );
-            return;
-            
-        } 
-        
-        if (e.getSource() == addButton) {
-            
-            String text = addText.getText();
-            
-            if (text==null) return;
-            
-            TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
-            if (treeNode == null) {
-                messageText.append("Must select a tree component to add a child to it.");
-                return;
-            }
-            TreePath path = new TreePath(
-                    ((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
-            if (path == null) {
-                setMessage("Could not create a path.");
-                return;
-            }
-            if(!jtree.getSelectionModel().isPathSelected(path))
-                return;
-            Node node = jtree.getNode(treeNode);
-            Node textNode = document.createTextNode(text);
-            try {
-                node.appendChild(textNode);
-            } catch (DOMException dome) {
-                setMessage("DOMException:"+dome.code+", "+dome);
-                return;
-            }
-            ((DOMTreeFull.Model)jtree.getModel()).insertNode(textNode, (MutableTreeNode)treeNode);
-            
-            return;
-        }
-        if (e.getSource() == nextButton) {          
-            Node node = iterator.nextNode();
-            if (node==null) {
-                setMessage("iterator.nextNode() == null");
-                return;
-            } 
-            
-            setMessage("iterator.nextNode() == "+node);
-
-            TreeNode treeNode = jtree.getTreeNode(node);
-            if (treeNode == null) {
-                setMessage("No JTree TreeNode for Node name:" + node.getNodeName());
-                return;
-            }
-            
-            TreePath path = new TreePath(
-                    ((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
-            jtree.requestFocus();
-            jtree.setSelectionPath(path);
-            jtree.scrollPathToVisible(path);
-            return;
-        } 
-        
-        if (e.getSource() == prevButton) {          
-            Node node = iterator.previousNode();
-            if (node==null) {
-                setMessage("iterator.previousNode() == null");
-                return;
-            } 
-            
-            setMessage("iterator.previousNode() == "+node);
-
-            TreeNode treeNode = jtree.getTreeNode(node);
-            if (treeNode == null) {
-                setMessage("No JTree TreeNode for Node name:" + node.getNodeName());
-                return;
-            }
-            
-            TreePath path = new TreePath(
-                    ((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
-            jtree.requestFocus();
-            jtree.setSelectionPath(path);
-            jtree.scrollPathToVisible(path);
-            return;
-        }
-        if (e.getSource() == removeButton) {
-            
-            /** If the node is not selected don't remove. */
-            TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
-            if (treeNode == null) {
-                messageText.append("Must select a tree component to remove it.");
-                return;
-            }
-            TreePath path = new TreePath(
-                    ((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
-            if (path == null) {
-                setMessage("Could not create a path.");
-                return;
-            }
-            if(!jtree.getSelectionModel().isPathSelected(path))
-                return;
-            Node node = jtree.getNode(treeNode);
-            if (node == null) return;
-            Node parent = node.getParentNode();
-            if (parent == null) return;
-            
-            parent.removeChild(node);
-    
-            ((DefaultTreeModel)jtree.getModel()).removeNodeFromParent((MutableTreeNode)treeNode);
-            return;
-        } 
-        
-    }
-    
-    /** Helper function to set messages */
-    void setMessage(String string) {
-        messageText.selectAll();
-        messageText.cut();
-        messageText.append(string);
-        messageText.setCaretPosition(0);
-    }
-        
-    /** called when our JTree's nodes are selected.
-     */
-    void nodeSelected(TreeNode treeNode) {
-
-        lastSelected = treeNode;
-        Node node = jtree.getNode(treeNode);
-        
-        System.out.println("nodeSelected.node="+node);
-        if (node == null) return;
-                            
-        setMessage(DOMTreeFull.toString(node));
-    }
-    
-    /** Utility function to expand the jtree */
-    void expandTree() {
-        for (int i = 0; i < jtree.getRowCount(); i++) {
-            jtree.expandRow(i);
-        }
-    }
-    
-    class Errors implements ErrorHandler {
-
-        Hashtable errorNodes = new Hashtable();
-
-        public void warning(SAXParseException ex) {
-            store(ex, "[Warning]");
-        }
-
-        public void error(SAXParseException ex) {
-            store(ex, "[Error]");
-        }
-
-        public void fatalError(SAXParseException ex) throws SAXException {
-            store(ex, "[Fatal Error]");
-        }
-
-        public Hashtable getErrorNodes() {
-            return errorNodes;
-        }
-
-        public Object getError(Node node) {
-            return errorNodes.get(node);
-        }
-
-        public void clearErrors() {
-            errorNodes.clear();
-        }
-
-        void store(SAXParseException ex, String type) {
-
-            // build error text
-            String errorString= type+" at line number, "+ex.getLineNumber()
-                +": "+ex.getMessage()+"\n";
-            Node currentNode = null;
-            try {
-                currentNode = (Node)parser.getProperty("http://apache.org/xml/properties/dom-node");
-            } catch (SAXException se) {
-                System.err.println(se.getMessage());
-                return;
-            }
-            if (currentNode == null) return;
-
-            // accumulate any multiple errors per node in the Hashtable.
-            String previous = (String) errorNodes.get(currentNode);
-            if (previous != null)
-                errorNodes.put(currentNode, previous +errorString);
-            else
-                errorNodes.put(currentNode, errorString);
-        }
-    }
-    
-}
diff --git a/samples/dom/traversal/Makefile b/samples/dom/traversal/Makefile
deleted file mode 100644
index 3156484..0000000
--- a/samples/dom/traversal/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# Makefile for directory ./dom/traversal
-
-TARGETS=\
-	IteratorView.class\
-	NameNodeFilter.class\
-	TreeWalkerView.class
-
-DIRS = 
-
-TOP = ../../..
-include $(TOP)/src/Makefile.incl
diff --git a/samples/dom/traversal/NameNodeFilter.java b/samples/dom/traversal/NameNodeFilter.java
deleted file mode 100644
index b3bca05..0000000
--- a/samples/dom/traversal/NameNodeFilter.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package dom.traversal;
-
-
-import org.w3c.dom.traversal.*;
-import org.w3c.dom.Node;
-import org.w3c.dom.Element;
-
- /** An example filter which enables the client to set a <b>name</b> value 
-  *  accept those node names which <b>match</b> (or explicitly <b>not match</b>) 
-  *  the set name value.
-  */
- public class NameNodeFilter implements NodeFilter {
-    
-    String fName;
-    boolean fMatch = true;
-            
-        /** The name to compare with the node name. If null, all node names  
-         *  are successfully matched. 
-         */
-        public void setName(String name) {
-            this.fName = name;
-        }
-        
-        /** Return the name to compare with node name. If null, all node names  
-         *  are successfully matched. */
-        public String getName() {
-            return this.fName;
-        }
-        
-        /** 
-         *  Controls whether the node name is accepted when it <b>does</b> match 
-         *  the setName value, or when it <b>does not</b> match the setName value. 
-         *  If the setName value is null this match value does not matter, and
-         *  all names will match.
-         *  If match is true, the node name is accepted when it matches. 
-         *  If match is false, the node name is accepted when does not match. 
-         */
-        public void setMatch(boolean match) {
-            this.fMatch = match;
-        }
-        
-        /** Return match value. */
-        public boolean getMatch() {
-            return this.fMatch;
-        }
-        
-        /** acceptNode determines if this filter accepts a node name or not. */ 
-        public short acceptNode(Node n) {
-
-            if (fName == null || fMatch && n.getNodeName().equals(fName) 
-            ||  !fMatch && !n.getNodeName().equals(fName))
-                return FILTER_ACCEPT;
-            else 
-                return FILTER_REJECT;
-        }
-    }
diff --git a/samples/dom/traversal/TreeWalkerView.java b/samples/dom/traversal/TreeWalkerView.java
deleted file mode 100644
index 4694ba9..0000000
--- a/samples/dom/traversal/TreeWalkerView.java
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package dom.traversal;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.Hashtable;
-import java.util.Enumeration;
-import javax.swing.*;
-import javax.swing.tree.*;
-import javax.swing.event.*;
-import org.apache.xerces.parsers.*;
-import org.w3c.dom.*;
-import org.w3c.dom.traversal.*;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-import ui.DOMTreeFull;
-
-/** This class shows a DOM Document in a JTree, and presents controls
- *  which allow the user to create and view the progress of a TreeWalker
- *  in the DOM tree.
- */
-public class TreeWalkerView 
-    extends JFrame 
-    implements ActionListener {
-
-    Document document;
-    TreeNode lastSelected;
-    DOMParser parser;
-    JTextArea messageText;
-    JScrollPane messageScroll;
-    DOMTreeFull jtree;
-    TreeWalker treeWalker;
-    NameNodeFilter nameNodeFilter;
-    
-    JButton nextButton;
-    JButton prevButton;
-    JButton removeButton;
-    JButton addButton;
-    JTextField addText;
-    JButton newIterator;
-    JList whatToShow;
-    JCheckBox match;
-    JTextField nameFilter;
-   
-    // treeWalker specific buttons    
-    JButton parentButton;
-    JButton nextSiblingButton;
-    JButton previousSiblingButton;
-    JButton firstChildButton;
-    JButton lastChildButton;
-    JButton currentButton;
-    
-    String whatArray[] = new String [] { 
-            "ALL",
-            "ELEMENT",
-            "ATTRIBUTE",
-            "TEXT",
-            "CDATA_SECTION",
-            "ENTITY_REFERENCE",
-            "ENTITY",
-            "PROCESSING_INSTRUCTION", 
-            "COMMENT", 
-            "DOCUMENT", 
-            "DOCUMENT_TYPE",
-            "DOCUMENT_FRAGMENT",
-            "NOTATION" 
-            };
-    JCheckBox expandERs;
-    
-    
-    /** main */
-    public static void main (String args[]) {
-
-        if (args.length > 0) {
-            String filename = args[0];
-            try {
-                TreeWalkerView frame = new TreeWalkerView(filename) ;
-                frame.addWindowListener(new java.awt.event.WindowAdapter() {
-                 public void windowClosing(java.awt.event.WindowEvent e) {
-                     System.exit(0);
-                 }
-                });
-                frame.setSize(640, 700);
-                frame.setVisible(true);
-                } catch (Exception e) {
-                    e.printStackTrace(System.err);
-                }
-        }
-    }
-    
-    Hashtable treeNodeMap = new Hashtable();
-
-    /** Constructor */
-    public TreeWalkerView (String filename) {
-        super("TreeWalkerView: "+filename);
-        try {
-            parser = new DOMParser();
-            parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", true);
-            parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
-            Errors errors = new Errors();
-            parser.setErrorHandler(errors);
-            parser.parse(filename);
-            document = parser.getDocument();
-            
-            if (!document.supports("Traversal", "2.0")) {
-                // This cannot happen with the DOMParser...
-                throw new RuntimeException("This DOM Document does not support Traversal");
-            
-            }
-
-            // jtree  UI setup
-            jtree = new DOMTreeFull((Node)document);
-            jtree.getSelectionModel().setSelectionMode
-                (TreeSelectionModel.SINGLE_TREE_SELECTION);
-
-            // Listen for when the selection changes, call nodeSelected(node)
-            jtree.addTreeSelectionListener(
-                new TreeSelectionListener() {
-                    public void valueChanged(TreeSelectionEvent e) {
-                        TreePath path = (TreePath)e.getPath(); 
-                        TreeNode treeNode = (TreeNode)path.getLastPathComponent();
-                        if(jtree.getSelectionModel().isPathSelected(path))
-                                nodeSelected(treeNode);
-                    }
-                }
-            );
-            
-            //            
-            // controls
-            //
-            
-            BorderLayout borderLayout = new BorderLayout();
-            
-            //iterate panel
-            JPanel iteratePanel = new JPanel();
-            iteratePanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("Document Order Traversal"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-            
-            prevButton = new JButton("Previous");
-            iteratePanel.add(prevButton);
-            prevButton.addActionListener(this);
-            
-            nextButton = new JButton("Next");
-            iteratePanel.add(nextButton);
-            nextButton.addActionListener(this);
-        
-            //walkerPanel
-            JPanel walkerPanel = new JPanel();
-            walkerPanel.setLayout(new BorderLayout());
-            walkerPanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("Walk"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-            
-            parentButton = new JButton("Parent");
-            walkerPanel.add(parentButton, BorderLayout.NORTH);
-            parentButton.addActionListener(this);
-           
-            
-            JPanel childPanel = new JPanel();
-            firstChildButton = new JButton("First Child");
-            childPanel.add(firstChildButton);
-            firstChildButton.addActionListener(this);
-   
-            lastChildButton = new JButton("Last Child");
-            childPanel.add(lastChildButton);
-            lastChildButton.addActionListener(this);
-            walkerPanel.add(childPanel, BorderLayout.SOUTH);
-            
-            nextSiblingButton = new JButton("Next Sibling");
-            walkerPanel.add(nextSiblingButton, BorderLayout.EAST);
-            nextSiblingButton.addActionListener(this);
-            
-            previousSiblingButton = new JButton("Previous Sibling");
-            walkerPanel.add(previousSiblingButton, BorderLayout.WEST);
-            previousSiblingButton.addActionListener(this);
-            
-            //DOM tree panel
-            JPanel domPanel = new JPanel();
-            domPanel.setLayout(new BorderLayout());
-            domPanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("Selected Node"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-            
-            JPanel buttonPanel = new JPanel();
-            currentButton = new JButton("Current");
-            buttonPanel.add(currentButton);
-            currentButton.addActionListener(this);
-   
-            removeButton = new JButton("Remove");
-            buttonPanel.add(removeButton);
-            removeButton.addActionListener(this);
-            
-            addButton = new JButton("Append Text");
-            addText = new JTextField(10);
-            buttonPanel.add(addButton);
-            domPanel.add(buttonPanel, BorderLayout.NORTH);
-            domPanel.add(addText, BorderLayout.CENTER);
-            addButton.addActionListener(this);
-         
-            // treeWalker settings
-            JPanel settingsPanel = new JPanel();
-            settingsPanel.setLayout(new BorderLayout());
-            settingsPanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("Filter Settings"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-            JPanel treeWalkerPanel = new JPanel();
-            treeWalkerPanel.setLayout(new BorderLayout());
-            
-            newIterator = new JButton("createTreeWalker");
-            treeWalkerPanel.add(newIterator, BorderLayout.NORTH);
-            expandERs = new JCheckBox("expandEntityReferences");
-            expandERs.setSelected(true);
-            treeWalkerPanel.add(expandERs, BorderLayout.SOUTH);
-            settingsPanel.add(treeWalkerPanel, BorderLayout.NORTH);
-            newIterator.addActionListener(this);
-    
-            JPanel whatPanel = new JPanel();
-            whatPanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("whatToShow"),
-                BorderFactory.createEmptyBorder(0, 0, 0, 0)
-                ));
-            whatToShow = new JList(whatArray);
-            JScrollPane whatScroll = 
-            new JScrollPane(whatToShow) {
-                    public Dimension getPreferredSize(){
-                        return new Dimension(200, 65 );
-                    }
-                };
-            
-            whatPanel.add(whatScroll);
-            
-            
-            JPanel filterPanel = new JPanel();
-            filterPanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("NodeNameFilter"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-            filterPanel.setLayout(new BorderLayout());
-            match = new JCheckBox("match/ignore node name", true);
-            nameFilter = new JTextField(10);
-            filterPanel.add(match, BorderLayout.NORTH);
-            filterPanel.add(nameFilter, BorderLayout.SOUTH);
-            
-            settingsPanel.add(treeWalkerPanel, BorderLayout.NORTH);
-            settingsPanel.add(whatPanel, BorderLayout.CENTER);
-            settingsPanel.add(filterPanel, BorderLayout.SOUTH);
-            
-
-            // Listen for when the selection changes, call nodeSelected(node)
-            whatToShow.addListSelectionListener(
-                new ListSelectionListener() {
-                    public void valueChanged(ListSelectionEvent e) {
-                        // do nothing on selection...
-                    }
-                }
-            );
-            
-            
-            JPanel controlsPanel = new JPanel(new BorderLayout());
-            controlsPanel.setFont(new Font("Dialog", Font.PLAIN, 8));
-            JPanel buttonsPanel = new JPanel(new BorderLayout());
-            buttonsPanel.add(iteratePanel, BorderLayout.NORTH);
-            buttonsPanel.add(walkerPanel, BorderLayout.CENTER);
-            buttonsPanel.add(domPanel, BorderLayout.SOUTH);
-            controlsPanel.add(buttonsPanel, BorderLayout.NORTH);
-            controlsPanel.add(settingsPanel, BorderLayout.CENTER);
-            
-            controlsPanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("Controls"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-                
-                
-            // tree panel    
-            JPanel treePanel = new JPanel(new BorderLayout());
-                
-            JScrollPane treeScroll = new JScrollPane(jtree) ;
-            treeScroll.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("Tree View"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-
-            // message text UI setup
-            messageText = new JTextArea(3,5);
-
-            JPanel messagePanel = new JPanel(new BorderLayout());
-            messageScroll = new JScrollPane(messageText);
-            messagePanel.add(messageScroll);
-            messagePanel.setBorder(BorderFactory.createCompoundBorder(
-                BorderFactory.createTitledBorder("Messages"),
-                BorderFactory.createEmptyBorder(4, 4, 4, 4)
-                ));
-            
-            JPanel mainPanel = new JPanel();
-            mainPanel.setLayout(new BorderLayout());
-            mainPanel.add(controlsPanel, BorderLayout.EAST);
-            mainPanel.add(treeScroll, BorderLayout.CENTER);
-            mainPanel.add(messagePanel, BorderLayout.SOUTH);
-            getContentPane().add(mainPanel);
-            
-            Hashtable errorNodes = errors.getErrorNodes();
-            Enumeration elements = errorNodes.elements();
-            while (elements.hasMoreElements()) {
-                //*** append errors to messageText
-                messageText.append( (String)elements.nextElement());
-            }    
-            
-            boolean expand = expandERs.isSelected();
-            treeWalker = ((DocumentTraversal)document).
-                createTreeWalker(
-                    document, 
-                    NodeFilter.SHOW_ALL, 
-                    new NameNodeFilter(),
-                    expand);
-            
-        } catch (Exception e) {
-            e.printStackTrace(System.err);
-        }
-    }
-               
-    public void actionPerformed(ActionEvent e) {
-        
-        if (e.getSource() == newIterator) {
-            
-            TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
-            if (treeNode == null) {
-                messageText.append("Must select a tree component.");
-                return;
-            }
-            
-            Node node = jtree.getNode(treeNode);
-            if (node == null) {
-                setMessage("No current Node in TreeNode: "+node);
-            }
-            
-            // whatToShow section
-            int  [] indices = whatToShow.getSelectedIndices();
-            int mask = 0x0;
-            for (int i = 0; i < indices.length; i++) {
-                if (indices[i] == 0) {
-                    mask = 0xFFFF;
-                    break;
-                } else {
-                    mask = mask | 1<<indices[i]-1;
-                }
-            }
-            
-            // filter section
-            String nameText = nameFilter.getText();
-            boolean matched = match.isSelected();
-            if (nameNodeFilter==null) {
-                nameNodeFilter = new NameNodeFilter();
-            }
-            if (nameText.equals("")) {
-                setMessage("NodeNameFilter name is \"\". Assuming null.");
-                nameText = null;
-            }
-            nameNodeFilter.setName(nameText);
-            nameNodeFilter.setMatch(matched);
-            
-            // expand Entity References?
-            boolean expand = expandERs.isSelected();
-            
-            treeWalker = ((DocumentTraversal)document).
-                createTreeWalker(
-                    node, 
-                    mask, 
-                    nameNodeFilter,
-                    expand);
-            setMessage("createTreeWalker:"+ 
-                        " root="+node+
-                        ", whatToShow="+mask+
-                        ", match="+matched+
-                        ", name="+nameText
-                        );
-            return;
-            
-        } 
-        
-        if (e.getSource() == currentButton) {
-            
-            TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
-            if (treeNode == null) {
-                messageText.append("Must select a tree component.");
-                return;
-            }
-            
-            Node node = jtree.getNode(treeNode);
-            if (node == null) {
-                setMessage("No current Node in TreeNode: "+node);
-            }
-            treeWalker.setCurrentNode(node);
-            return;
-            
-        }
-        if (e.getSource() == addButton) {
-            
-            String text = addText.getText();
-            
-            if (text==null) return;
-            
-            TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
-            if (treeNode == null) {
-                messageText.append("Must select a tree component to add a child to it.");
-                return;
-            }
-            TreePath path = new TreePath(
-                    ((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
-            if (path == null) {
-                setMessage("Could not create a path.");
-                return;
-            }
-            if(!jtree.getSelectionModel().isPathSelected(path))
-                return;
-            Node node = jtree.getNode(treeNode);
-            Node textNode = document.createTextNode(text);
-            try {
-                node.appendChild(textNode);
-            } catch (DOMException dome) {
-                setMessage("DOMException:"+dome.code+", "+dome);
-                return;
-            }
-            ((DOMTreeFull.Model)jtree.getModel()).insertNode(textNode, (MutableTreeNode)treeNode);
-            
-            return;
-        }
-        
-        if (e.getSource() == removeButton) {
-
-            /** If the node is not selected don't remove. */
-            TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
-            if (treeNode == null) {
-                messageText.append("Must select a tree component to remove it.");
-                return;
-            }
-            TreePath path = new TreePath(
-                    ((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
-            if (path == null) {
-                setMessage("Could not create a path.");
-                return;
-            }
-            if(!jtree.getSelectionModel().isPathSelected(path))
-                return;
-            Node node = jtree.getNode(treeNode);
-            if (node == null) return;
-            Node parent = node.getParentNode();
-            if (parent == null) return;
-
-            parent.removeChild(node);
-    
-            ((DefaultTreeModel)jtree.getModel()).removeNodeFromParent((MutableTreeNode)treeNode);
-            return;
-        } 
-        
-        if (e.getSource() == previousSiblingButton) {          
-            Node node = treeWalker.previousSibling();
-            handleButton(node, "previousSibling()");
-            return;
-        } 
-        
-        if (e.getSource() == firstChildButton) {          
-            Node node = treeWalker.firstChild();
-            handleButton(node, "firstChild()");
-            return;
-        } 
-        
-        if (e.getSource() == lastChildButton) {          
-            Node node = treeWalker.lastChild();
-            handleButton(node, "lastChild()");
-            return;
-        } 
-        
-        if (e.getSource() == nextSiblingButton) {          
-            Node node = treeWalker.nextSibling();
-            handleButton(node, "nextSibling()");
-            return;
-        } 
-        
-        if (e.getSource() == parentButton) {          
-            Node node = treeWalker.parentNode();
-            handleButton(node, "parentNode()");
-            return;
-        } 
-        
-        if (e.getSource() == nextButton) {          
-            Node node = treeWalker.nextNode();
-            handleButton(node, "nextNode()");
-            return;
-        } 
-        
-        if (e.getSource() == prevButton) {          
-            Node node = treeWalker.previousNode();
-            handleButton(node, "previousNode()");
-            return;
-        }
-        
-    }
-    
-    /** handle a button press: output messages and select node. */
-    void handleButton( Node node, String function) {
-        
-        setMessage("treeWalker."+function+" == "+node);
-   
-        if (node==null) return;
-
-        TreeNode treeNode = jtree.getTreeNode(node);
-        if (treeNode == null) {
-            setMessage("No JTree TreeNode for Node name:" + node.getNodeName());
-            return;
-        }
-            
-        TreePath path = new TreePath(
-                ((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
-        jtree.requestFocus();
-        jtree.setSelectionPath(path);
-        jtree.scrollPathToVisible(path);
-    }
-    
-    /** Helper function to set messages */
-    void setMessage(String string) {
-        messageText.selectAll();
-        messageText.cut();
-        messageText.append(string);
-        messageText.setCaretPosition(0);
-    }
-        
-    /** called when our JTree's nodes are selected.
-     */
-    void nodeSelected(TreeNode treeNode) {
-
-        lastSelected = treeNode;
-        Node node = jtree.getNode(treeNode);
-        
-        if (node == null) return;
-                            
-        setMessage(DOMTreeFull.toString(node));
-    }
-    
-    /** Utility function to expand the jtree */
-    void expandTree() {
-        for (int i = 0; i < jtree.getRowCount(); i++) {
-            jtree.expandRow(i);
-        }
-    }
-    
-    class Errors implements ErrorHandler {
-
-        Hashtable errorNodes = new Hashtable();
-
-        public void warning(SAXParseException ex) {
-            store(ex, "[Warning]");
-        }
-
-        public void error(SAXParseException ex) {
-            store(ex, "[Error]");
-        }
-
-        public void fatalError(SAXParseException ex) throws SAXException {
-            store(ex, "[Fatal Error]");
-        }
-
-        public Hashtable getErrorNodes() {
-            return errorNodes;
-        }
-
-        public Object getError(Node node) {
-            return errorNodes.get(node);
-        }
-
-        public void clearErrors() {
-            errorNodes.clear();
-        }
-
-        void store(SAXParseException ex, String type) {
-
-            // build error text
-            String errorString= type+" at line number, "+ex.getLineNumber()
-                +": "+ex.getMessage()+"\n";
-
-            Node currentNode = null;
-            try {
-                currentNode = (Node)parser.getProperty("http://apache.org/xml/properties/dom-node");
-            } catch (SAXException se) {
-                System.err.println(se.getMessage());
-                return;
-            }
-            if (currentNode == null) return;
-
-            // accumulate any multiple errors per node in the Hashtable.
-            String previous = (String) errorNodes.get(currentNode);
-            if (previous != null)
-                errorNodes.put(currentNode, previous +errorString);
-            else
-                errorNodes.put(currentNode, errorString);
-        }
-    }
-    
-}
diff --git a/samples/dom/wrappers/DOMParser.java b/samples/dom/wrappers/DOMParser.java
deleted file mode 100644
index f9f0db8..0000000
--- a/samples/dom/wrappers/DOMParser.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package dom.wrappers;
-
-import dom.DOMParserWrapper;
-
-import org.w3c.dom.Document;
-
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.SAXNotRecognizedException;
-import org.xml.sax.SAXNotSupportedException;
-
-/**
- * Wraps the Xerces DOM parser and extends NonValidatingDOMParser
- *
- * @version  $id$
- */
-public class DOMParser 
-    implements DOMParserWrapper, ErrorHandler {
-
-    //
-    // Data
-    //
-
-
-
-    /** Parser. */
-    org.apache.xerces.parsers.DOMParser parser = 
-        new org.apache.xerces.parsers.DOMParser();
-
-    //
-    // Constructors
-    //
-
-    /** Default constructor. */
-    public DOMParser() {
-        try {
-            parser.setFeature( "http://xml.org/sax/features/validation", true);
-
-        } catch (SAXException e) {
-            System.out.println("error in setting up parser feature");
-        }
-
-        parser.setErrorHandler(this);
-
-    }
-
-    //
-    // DOMParserWrapper methods
-    //
-
-    /** Parses the specified URI and returns the document. */
-    public Document parse(String uri) throws Exception {
-        parser.parse(uri);
-        return parser.getDocument();
-
-    } // parse(String):Document
-
-
-    public void     setFeature(String featureId, boolean state)
-            throws  SAXNotRecognizedException, SAXNotSupportedException {
-            parser.setFeature( featureId, state );
-    }
-
-
-   
-    //
-    // ErrorHandler methods
-    //
-
-    /** Warning. */
-    public void warning(SAXParseException ex) {
-        System.err.println("[Warning] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-    }
-
-    /** Error. */
-    public void error(SAXParseException ex) {
-        System.err.println("[Error] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-    }
-
-    /** Fatal error. */
-    public void fatalError(SAXParseException ex) throws SAXException {
-        System.err.println("[Fatal Error] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-        throw ex;
-    }
-
-    //
-    // Private methods
-    //
-
-    /** Returns a string of the location. */
-    private String getLocationString(SAXParseException ex) {
-        StringBuffer str = new StringBuffer();
-
-        String systemId = ex.getSystemId();
-        if (systemId != null) {
-            int index = systemId.lastIndexOf('/');
-            if (index != -1) 
-                systemId = systemId.substring(index + 1);
-            str.append(systemId);
-        }
-        str.append(':');
-        str.append(ex.getLineNumber());
-        str.append(':');
-        str.append(ex.getColumnNumber());
-
-        return str.toString();
-
-    } // getLocationString(SAXParseException):String
-
-} // class DOMParser
diff --git a/samples/dom/wrappers/Makefile b/samples/dom/wrappers/Makefile
deleted file mode 100644
index 36002f9..0000000
--- a/samples/dom/wrappers/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# Makefile for directory ./dom/wrappers
-
-TARGETS=\
-	DOMParser.class
-
-DIRS = 
-
-TOP = ../../..
-include $(TOP)/src/Makefile.incl
diff --git a/samples/sax/Makefile b/samples/sax/Makefile
deleted file mode 100644
index 1fb06f3..0000000
--- a/samples/sax/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Makefile for directory ./sax
-
-TARGETS=\
-	SAXCount.class\
-	SAX2Count.class\
-	SAXWriter.class\
-	SAX2Writer.class
-
-DIRS = helpers
-
-TOP = ../..
-include $(TOP)/src/Makefile.incl
diff --git a/samples/sax/SAX2Count.java b/samples/sax/SAX2Count.java
deleted file mode 100644
index 2d6219a..0000000
--- a/samples/sax/SAX2Count.java
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package sax;                    
-
-import  util.Arguments;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-
-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;
-
-/**
- * A sample SAX2 counter. This sample program illustrates how to
- * register a SAX2 ContentHandler and receive the callbacks in
- * order to print information about the document.
- *
- * @version $Id$
- */
-public class SAX2Count 
-extends DefaultHandler {
-
-    //
-    // Constants
-    //
-
-    /** Default parser name. */
-    private static final String 
-    DEFAULT_PARSER_NAME = "org.apache.xerces.parsers.SAXParser";
-
-
-    private static boolean setValidation    = false; //defaults
-    private static boolean setNameSpaces    = true;
-    private static boolean setSchemaSupport = true;
-
-
-
-    //
-    // Data
-    //
-
-    private static boolean warmup = false;
-
-    /** Elements. */
-    private long elements;
-
-    /** Attributes. */
-    private long attributes;
-
-    /** Characters. */
-    private long characters;
-
-    /** Ignorable whitespace. */
-    private long ignorableWhitespace;
-
-    //
-    // Public static methods
-    //
-
-    /** Prints the output from the SAX callbacks. */
-    public static void print(String parserName, String uri, boolean validate) {
-
-        try {
-            SAX2Count counter = new SAX2Count();
-
-            XMLReader parser = (XMLReader)Class.forName(parserName).newInstance();
-            parser.setContentHandler(counter);
-            parser.setErrorHandler(counter);
-
-
-
-            //if (validate)
-            //   parser.setFeature("http://xml.org/sax/features/validation", true);
-
-            parser.setFeature( "http://xml.org/sax/features/validation", 
-                                               validate);
-
-            parser.setFeature( "http://xml.org/sax/features/namespaces",
-                                               setNameSpaces );
-
-            parser.setFeature( "http://apache.org/xml/features/validation/schema",
-                                               setSchemaSupport );
-
-            if (warmup) {
-                parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
-                parser.parse(uri);
-                warmup = false;
-            }
-            long before = System.currentTimeMillis();
-            parser.parse(uri);
-            long after = System.currentTimeMillis();
-            counter.printResults(uri, after - before);
-        } catch (org.xml.sax.SAXParseException spe) {
-            spe.printStackTrace(System.err);
-        } catch (org.xml.sax.SAXException se) {
-            if (se.getException() != null)
-                se.getException().printStackTrace(System.err);
-            else
-                se.printStackTrace(System.err);
-        } catch (Exception e) {
-            e.printStackTrace(System.err);
-        }
-
-    } // print(String,String)
-
-    //
-    // DocumentHandler methods
-    //
-
-    /** Start document. */
-    public void startDocument() {
-
-        if (warmup)
-            return;
-
-        elements            = 0;
-        attributes          = 0;
-        characters          = 0;
-        ignorableWhitespace = 0;
-
-    } // startDocument()
-
-    /** Start element. */
-    public void startElement(String uri, String local, String raw, Attributes attrs) {
-
-        if (warmup)
-            return;
-
-        elements++;
-        if (attrs != null) {
-            attributes += attrs.getLength();
-        }
-
-    } // startElement(String,AttributeList)
-
-    /** Characters. */
-    public void characters(char ch[], int start, int length) {
-
-        if (warmup)
-            return;
-
-        characters += length;
-
-    } // characters(char[],int,int);
-
-    /** Ignorable whitespace. */
-    public void ignorableWhitespace(char ch[], int start, int length) {
-
-        if (warmup)
-            return;
-
-        ignorableWhitespace += length;
-
-    } // ignorableWhitespace(char[],int,int);
-
-    //
-    // ErrorHandler methods
-    //
-
-    /** Warning. */
-    public void warning(SAXParseException ex) {
-        if (warmup)
-            return;
-
-        System.err.println("[Warning] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-    }
-
-    /** Error. */
-    public void error(SAXParseException ex) {
-        if (warmup)
-            return;
-
-        System.err.println("[Error] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-    }
-
-    /** Fatal error. */
-    public void fatalError(SAXParseException ex) throws SAXException {
-        if (warmup)
-            return;
-
-        System.err.println("[Fatal Error] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-//        throw ex;
-    }
-
-    /** Returns a string of the location. */
-    private String getLocationString(SAXParseException ex) {
-        StringBuffer str = new StringBuffer();
-
-        String systemId = ex.getSystemId();
-        if (systemId != null) {
-            int index = systemId.lastIndexOf('/');
-            if (index != -1)
-                systemId = systemId.substring(index + 1);
-            str.append(systemId);
-        }
-        str.append(':');
-        str.append(ex.getLineNumber());
-        str.append(':');
-        str.append(ex.getColumnNumber());
-
-        return str.toString();
-
-    } // getLocationString(SAXParseException):String
-
-    //
-    // Public methods
-    //
-
-    /** Prints the results. */
-    public void printResults(String uri, long time) {
-
-        // filename.xml: 631 ms (4 elems, 0 attrs, 78 spaces, 0 chars)
-        System.out.print(uri);
-        System.out.print(": ");
-        System.out.print(time);
-        System.out.print(" ms (");
-        System.out.print(elements);
-        System.out.print(" elems, ");
-        System.out.print(attributes);
-        System.out.print(" attrs, ");
-        System.out.print(ignorableWhitespace);
-        System.out.print(" spaces, ");
-        System.out.print(characters);
-        System.out.print(" chars)");
-        System.out.println();
-    } // printResults(String,long)
-
-    //
-    // Main
-    //
-
-    /** Main program entry point. */
-    public static void main(String argv[]) {
-
-        Arguments argopt = new Arguments();
-        argopt.setUsage( new String[] 
-                         { "usage: java sax.SAX2Count (options) uri ...","",
-                             "options:",
-                             "  -p name  Specify SAX parser by name.",
-                             "  -n | -N  Turn on/off namespace [default=on]",
-                             "  -v | -V  Turn on/off validation [default=off]",
-                             "  -s | -S  Turn on/off Schema support [default=on]",
-                             "  -d | -D  Turn on/off deferred DOM [default=on]",
-                             "  -w       Warmup the parser before timing.",
-                             "  -h       This help screen."}  );
-
-
-        // is there anything to do?
-        if (argv.length == 0) {
-            argopt.printUsage();
-            System.exit(1);
-        }
-
-        // vars
-        String  parserName = DEFAULT_PARSER_NAME;
-
-        argopt.parseArgumentTokens(argv, new char[] { 'p'} );
-
-        int   c;
-        String arg = null; 
-        while ( ( arg =  argopt.getlistFiles() ) != null ) {
-            outer:
-          
-            while ( (c =  argopt.getArguments()) != -1 ){
-                //System.out.println( "c =" + c );
-                switch (c) {
-                case 'v':
-                    setValidation = true;
-                    break;
-                case 'V':
-                    setValidation = false;
-                    break;
-                case 'N':
-                    setNameSpaces = false;
-                    break;
-                case 'n':
-                    setNameSpaces = true;
-                    break;
-                case 'p':
-                    parserName = argopt.getStringParameter();
-                    break;
-                case 's':
-                    setSchemaSupport = true;
-                    break;
-                case 'S':
-                    setSchemaSupport = false;
-                    break;
-                case '?':
-                case 'h':
-                case '-':
-                    argopt.printUsage();
-                    System.exit(1);
-                    break;
-                case 'w':
-                    warmup = true;
-                    break;
-                case -1:
-                    break outer;
-                default:
-                    break;
-                }
-
-            }
-            
-            // print uri
-            print(parserName, arg,  setValidation);
-            ///
-        }
-    } // main(String[])
-
-} // class SAX2Count
diff --git a/samples/sax/SAX2Writer.java b/samples/sax/SAX2Writer.java
deleted file mode 100644
index 12ddb60..0000000
--- a/samples/sax/SAX2Writer.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package sax;                    
-                    
-import util.Arguments;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-
-import sax.helpers.AttributesImpl;
-
-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;
-
-/**
- * A sample SAX2 writer. This sample program illustrates how to
- * register a SAX2 ContentHandler and receive the callbacks in
- * order to print a document that is parsed.
- *
- * @version $Id$
- */
-public class SAX2Writer 
-    extends DefaultHandler {
-
-    //
-    // Constants
-    //
-
-    /** Default parser name. */
-    private static final String 
-        DEFAULT_PARSER_NAME = "org.apache.xerces.parsers.SAXParser";
-
-
-    private static boolean setValidation    = false; //defaults
-    private static boolean setNameSpaces    = true;
-    private static boolean setSchemaSupport = true;
-
-
-    //
-    // Data
-    //
-
-    /** Print writer. */
-    protected PrintWriter out;
-
-    /** Canonical output. */
-    protected boolean canonical;
-
-    //
-    // Constructors
-    //
-
-    /** Default constructor. */
-    public SAX2Writer(boolean canonical) throws UnsupportedEncodingException {
-        this(null, canonical);
-    }
-
-    protected SAX2Writer(String encoding, boolean canonical) throws UnsupportedEncodingException {
-
-        if (encoding == null) {
-            encoding = "UTF8";
-        }
-
-        out = new PrintWriter(new OutputStreamWriter(System.out, encoding));
-        this.canonical = canonical;
-
-    } // <init>(String,boolean)
-
-    //
-    // Public static methods
-    //
-
-    /** Prints the output from the SAX callbacks. */
-    public static void print(String parserName, String uri, boolean canonical) {
-
-        try {
-            DefaultHandler handler = new SAX2Writer(canonical);
-
-            XMLReader parser = (XMLReader)Class.forName(parserName).newInstance();
-
-            parser.setFeature( "http://xml.org/sax/features/validation", 
-                                                setValidation);
-            parser.setFeature( "http://xml.org/sax/features/namespaces",
-                                                setNameSpaces );
-            parser.setFeature( "http://apache.org/xml/features/validation/schema",
-                                                setSchemaSupport );
-
-
-            parser.setContentHandler(handler);
-            parser.setErrorHandler(handler);
-            parser.parse(uri);
-        }
-        catch (Exception e) {
-            e.printStackTrace(System.err);
-        }
-
-    } // print(String,String,boolean)
-
-    //
-    // DocumentHandler methods
-    //
-
-    /** Processing instruction. */
-    public void processingInstruction(String target, String data) {
-
-        out.print("<?");
-        out.print(target);
-        if (data != null && data.length() > 0) {
-            out.print(' ');
-            out.print(data);
-        }
-        out.print("?>");
-        out.flush();
-
-    } // processingInstruction(String,String)
-
-    /** Start document. */
-    public void startDocument() {
-
-        if (!canonical) {
-            out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-            out.flush();
-        }
-
-    } // startDocument()
-
-    /** Start element. */
-    public void startElement(String uri, String local, String raw, 
-                             Attributes attrs) {
-
-        out.print('<');
-        out.print(raw);
-        if (attrs != null) {
-            attrs = sortAttributes(attrs);
-            int len = attrs.getLength();
-            for (int i = 0; i < len; i++) {
-                out.print(' ');
-                out.print(attrs.getQName(i));
-                out.print("=\"");
-                out.print(normalize(attrs.getValue(i)));
-                out.print('"');
-            }
-        }
-        out.print('>');
-        out.flush();
-
-    } // startElement(String,String,String,Attributes)
-
-    /** Characters. */
-    public void characters(char ch[], int start, int length) {
-
-        out.print(normalize(new String(ch, start, length)));
-        out.flush();
-
-    } // characters(char[],int,int);
-
-    /** Ignorable whitespace. */
-    public void ignorableWhitespace(char ch[], int start, int length) {
-
-        characters(ch, start, length);
-        out.flush();
-
-    } // ignorableWhitespace(char[],int,int);
-
-    /** End element. */
-    public void endElement(String uri, String local, String raw) {
-
-        out.print("</");
-        out.print(raw);
-        out.print('>');
-        out.flush();
-
-    } // endElement(String)
-
-    //
-    // ErrorHandler methods
-    //
-
-    /** Warning. */
-    public void warning(SAXParseException ex) {
-        System.err.println("[Warning] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-    }
-
-    /** Error. */
-    public void error(SAXParseException ex) {
-        System.err.println("[Error] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-    }
-
-    /** Fatal error. */
-    public void fatalError(SAXParseException ex) throws SAXException {
-        System.err.println("[Fatal Error] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-        throw ex;
-    }
-
-    /** Returns a string of the location. */
-    private String getLocationString(SAXParseException ex) {
-        StringBuffer str = new StringBuffer();
-
-        String systemId = ex.getSystemId();
-        if (systemId != null) {
-            int index = systemId.lastIndexOf('/');
-            if (index != -1) 
-                systemId = systemId.substring(index + 1);
-            str.append(systemId);
-        }
-        str.append(':');
-        str.append(ex.getLineNumber());
-        str.append(':');
-        str.append(ex.getColumnNumber());
-
-        return str.toString();
-
-    } // getLocationString(SAXParseException):String
-
-    //
-    // Protected static methods
-    //
-
-    /** Normalizes the given string. */
-    protected String normalize(String s) {
-        StringBuffer str = new StringBuffer();
-
-        int len = (s != null) ? s.length() : 0;
-        for (int i = 0; i < len; i++) {
-            char ch = s.charAt(i);
-            switch (ch) {
-                case '<': {
-                    str.append("&lt;");
-                    break;
-                }
-                case '>': {
-                    str.append("&gt;");
-                    break;
-                }
-                case '&': {
-                    str.append("&amp;");
-                    break;
-                }
-                case '"': {
-                    str.append("&quot;");
-                    break;
-                }
-                case '\r':
-                case '\n': {
-                    if (canonical) {
-                        str.append("&#");
-                        str.append(Integer.toString(ch));
-                        str.append(';');
-                        break;
-                    }
-                    // else, default append char
-                }
-                default: {
-                    str.append(ch);
-                }
-            }
-        }
-
-        return str.toString();
-
-    } // normalize(String):String
-
-    /** Returns a sorted list of attributes. */
-    protected Attributes sortAttributes(Attributes attrs) {
-
-        AttributesImpl attributes = new AttributesImpl();
-
-        int len = (attrs != null) ? attrs.getLength() : 0;
-        for (int i = 0; i < len; i++) {
-            String name = attrs.getQName(i);
-            int count = attributes.getLength();
-            int j = 0;
-            while (j < count) {
-                if (name.compareTo(attributes.getQName(j)) < 0) {
-                    break;
-                }
-                j++;
-            }
-            attributes.insertAttributeAt(j, name, attrs.getType(i), 
-                                         attrs.getValue(i));
-        }
-
-        return attributes;
-
-    } // sortAttributes(AttributeList):AttributeList
-
-    //
-    // Main
-    //
-
-      /** Main program entry point. */
-    public static void main(String argv[]) {
-        ///
-        Arguments argopt = new Arguments();
-
-        argopt.setUsage( new String[] {
-                             "usage: java sax.SAX2Writer (options) uri ...","",
-                             "options:",
-                             "  -n | -N  Turn on/off namespace [default=on]",
-                             "  -v | -V  Turn on/off validation [default=on]",
-                             "  -s | -S  Turn on/off Schema support [default=on]",
-                             "  -c       Canonical XML output.",
-                             "  -h       This help screen."} );
-
-
-
-
-        // is there anything to do?
-        if (argv.length == 0) {
-            argopt.printUsage();
-            System.exit(1);
-        }
-
-        // vars
-        boolean canonical  = false;
-        String  parserName = DEFAULT_PARSER_NAME;
-
-
-        argopt.parseArgumentTokens(argv, new char[] { 'p'} );
-
-        int   c;
-        String arg = null; 
-        while ( ( arg =  argopt.getlistFiles() ) != null ) {
-
-            outer:
-            while ( (c =  argopt.getArguments()) != -1 ){
-                switch (c) {
-                case 'c':
-                    canonical     = true;
-                    break;
-                case 'C':
-                    canonical     = false;
-                    break;
-                case 'v':
-                    setValidation = true;
-                    break;
-                case 'V':
-                    setValidation = false;
-                    break;
-                case 'N':
-                    setNameSpaces = false;
-                    break;
-                case 'n':
-                    setNameSpaces = true;
-                    break;
-                case 'p':
-                    parserName = argopt.getStringParameter();
-                    break;
-                case 's':
-                    setSchemaSupport = true;
-                    break;
-                case 'S':
-                    setSchemaSupport = false;
-                    break;
-                case '?':
-                case 'h':
-                case '-':
-                    argopt.printUsage();
-                    System.exit(1);
-                    break;
-                case -1:
-                    break outer;
-                default:
-                    break;
-                }
-            }
-            // print 
-            System.err.println(arg+':');
-            print(parserName, arg, canonical);
-        }
-    } // main(String[])
-
-} // class SAX2Writer
diff --git a/samples/sax/SAXCount.java b/samples/sax/SAXCount.java
deleted file mode 100644
index 2a7b07f..0000000
--- a/samples/sax/SAXCount.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package sax;                    
-
-import util.Arguments;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-
-import sax.helpers.AttributeListImpl;
-
-import org.xml.sax.AttributeList;
-import org.xml.sax.HandlerBase;
-import org.xml.sax.Parser;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.ParserFactory;
-
-/**
- * A sample SAX counter. This sample program illustrates how to
- * register a SAX DocumentHandler and receive the callbacks in
- * order to print information about the document.
- *
- * @version
- */
-public class SAXCount 
-extends HandlerBase {
-
-    //
-    // Constants
-    //
-
-    /** Default parser name. */
-    private static final String 
-    DEFAULT_PARSER_NAME = "org.apache.xerces.parsers.SAXParser";
-
-
-    private static boolean setValidation    = false; //defaults
-    private static boolean setNameSpaces    = true;
-    private static boolean setSchemaSupport = true;
-
-
-    //
-    // Data
-    //
-
-    private static boolean warmup = false;
-
-    /** Elements. */
-    private long elements;
-
-    /** Attributes. */
-    private long attributes;
-
-    /** Characters. */
-    private long characters;
-
-    /** Ignorable whitespace. */
-    private long ignorableWhitespace;
-
-    //
-    // Public static methods
-    //
-
-    /** Prints the output from the SAX callbacks. */
-    public static void print(String parserName, String uri, boolean validate) {
-
-        try {
-            SAXCount counter = new SAXCount();
-
-            Parser parser = ParserFactory.makeParser(parserName);
-            parser.setDocumentHandler(counter);
-            parser.setErrorHandler(counter);
-            try {
-                //if (validate && parser instanceof XMLReader)
-                if ( parser instanceof XMLReader ){
-                    ((XMLReader)parser).setFeature( "http://xml.org/sax/features/validation", 
-                                                    validate);
-                    ((XMLReader)parser).setFeature( "http://xml.org/sax/features/namespaces",
-                                                    setNameSpaces );
-                    ((XMLReader)parser).setFeature( "http://apache.org/xml/features/validation/schema",
-                                                    setSchemaSupport );
-
-                }
-            } catch (Exception ex) {
-            }
-
-            if (warmup) {
-                if (parser instanceof XMLReader)
-                    ((XMLReader)parser).setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
-
-                parser.parse(uri);
-                warmup = false;
-            }
-            long before = System.currentTimeMillis();
-            parser.parse(uri);
-            long after = System.currentTimeMillis();
-            counter.printResults(uri, after - before);
-        } catch (org.xml.sax.SAXParseException spe) {
-            spe.printStackTrace(System.err);
-        } catch (org.xml.sax.SAXException se) {
-            if (se.getException() != null)
-                se.getException().printStackTrace(System.err);
-            else
-                se.printStackTrace(System.err);
-        } catch (Exception e) {
-            e.printStackTrace(System.err);
-        }
-
-    } // print(String,String)
-
-    //
-    // DocumentHandler methods
-    //
-
-    /** Start document. */
-    public void startDocument() {
-
-        if (warmup)
-            return;
-
-        elements            = 0;
-        attributes          = 0;
-        characters          = 0;
-        ignorableWhitespace = 0;
-
-    } // startDocument()
-
-    /** Start element. */
-    public void startElement(String name, AttributeList attrs) {
-
-        if (warmup)
-            return;
-
-        elements++;
-        if (attrs != null) {
-            attributes += attrs.getLength();
-        }
-
-    } // startElement(String,AttributeList)
-
-    /** Characters. */
-    public void characters(char ch[], int start, int length) {
-
-        if (warmup)
-            return;
-
-        characters += length;
-
-    } // characters(char[],int,int);
-
-    /** Ignorable whitespace. */
-    public void ignorableWhitespace(char ch[], int start, int length) {
-
-        if (warmup)
-            return;
-
-        ignorableWhitespace += length;
-
-    } // ignorableWhitespace(char[],int,int);
-
-    //
-    // ErrorHandler methods
-    //
-
-    /** Warning. */
-    public void warning(SAXParseException ex) {
-        if (warmup)
-            return;
-
-        System.err.println("[Warning] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-    }
-
-    /** Error. */
-    public void error(SAXParseException ex) {
-        if (warmup)
-            return;
-
-        System.err.println("[Error] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-    }
-
-    /** Fatal error. */
-    public void fatalError(SAXParseException ex) throws SAXException {
-        if (warmup)
-            return;
-
-        System.err.println("[Fatal Error] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-//        throw ex;
-    }
-
-    /** Returns a string of the location. */
-    private String getLocationString(SAXParseException ex) {
-        StringBuffer str = new StringBuffer();
-
-        String systemId = ex.getSystemId();
-        if (systemId != null) {
-            int index = systemId.lastIndexOf('/');
-            if (index != -1)
-                systemId = systemId.substring(index + 1);
-            str.append(systemId);
-        }
-        str.append(':');
-        str.append(ex.getLineNumber());
-        str.append(':');
-        str.append(ex.getColumnNumber());
-
-        return str.toString();
-
-    } // getLocationString(SAXParseException):String
-
-    //
-    // Public methods
-    //
-
-    /** Prints the results. */
-    public void printResults(String uri, long time) {
-
-        // filename.xml: 631 ms (4 elems, 0 attrs, 78 spaces, 0 chars)
-        System.out.print(uri);
-        System.out.print(": ");
-        System.out.print(time);
-        System.out.print(" ms (");
-        System.out.print(elements);
-        System.out.print(" elems, ");
-        System.out.print(attributes);
-        System.out.print(" attrs, ");
-        System.out.print(ignorableWhitespace);
-        System.out.print(" spaces, ");
-        System.out.print(characters);
-        System.out.print(" chars)");
-        System.out.println();
-    } // printResults(String,long)
-
-    //
-    // Main
-    //
-
-                            /** Main program entry point. */
-    public static void main(String argv[]) {
-
-        Arguments argopt = new Arguments();
-        argopt.setUsage( new String[] 
-                         { "usage: java sax.SAXCount (options) uri ...","",
-                             "options:",
-                             "  -p name  Specify SAX parser by name.",
-                             "  -n | -N  Turn on/off namespace [default=on]",
-                             "  -v | -V  Turn on/off validation [default=off]",
-                             "  -s | -S  Turn on/off Schema support [default=on]",
-                             "  -d | -D  Turn on/off deferred DOM [default=on]",
-                             "  -w       Warmup the parser before timing.",
-                             "  -h       This help screen."}  );
-
-
-        // is there anything to do?
-        if (argv.length == 0) {
-            argopt.printUsage();
-            System.exit(1);
-        }
-
-        // vars
-        String  parserName = DEFAULT_PARSER_NAME;
-
-        argopt.parseArgumentTokens(argv, new char[]  { 'p'} );
-
-        int   c;
-        String arg = null; 
-        while ( ( arg =  argopt.getlistFiles() ) != null ) {
-            outer:
-            while ( (c =  argopt.getArguments()) != -1 ){
-                switch (c) {
-                case 'v':
-                    setValidation = true;
-                    break;
-                case 'V':
-                    setValidation = false;
-                    break;
-                case 'N':
-                    setNameSpaces = false;
-                    break;
-                case 'n':
-                    setNameSpaces = true;
-                    break;
-                case 'p':
-                    parserName = argopt.getStringParameter();
-                    break;
-                case 's':
-                    setSchemaSupport = true;
-                    break;
-                case 'S':
-                    setSchemaSupport = false;
-                    break;
-                case '?':
-                case 'h':
-                case '-':
-                    argopt.printUsage();
-                    System.exit(1);
-                    break;
-                case 'w':
-                    warmup = true;
-                    break;
-                case -1:
-                    break outer;
-                default:
-                    break;
-                }
-
-            }
-            
-            // print uri
-            print(parserName, arg,  setValidation);
-            ///
-        }
-    } // main(String[])
-
-} // class SAXCount
diff --git a/samples/sax/SAXWriter.java b/samples/sax/SAXWriter.java
deleted file mode 100644
index 4c8525c..0000000
--- a/samples/sax/SAXWriter.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package sax;                    
-
-import util.Arguments;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-
-import sax.helpers.AttributeListImpl;
-
-import org.xml.sax.AttributeList;
-import org.xml.sax.HandlerBase;
-import org.xml.sax.Parser;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.helpers.ParserFactory;
-import org.xml.sax.XMLReader;
-
-
-
-/**
- * A sample SAX writer. This sample program illustrates how to
- * register a SAX DocumentHandler and receive the callbacks in
- * order to print a document that is parsed.
- *
- * @version
- */
-public class SAXWriter 
-extends HandlerBase {
-
-    //
-    // Constants
-    //
-
-    /** Default parser name. */
-    private static final String 
-    DEFAULT_PARSER_NAME = "org.apache.xerces.parsers.SAXParser";
-
-    private static boolean setValidation    = false; //defaults
-    private static boolean setNameSpaces    = true;
-    private static boolean setSchemaSupport = true;
-
-
-
-
-    //
-    // Data
-    //
-
-    /** Print writer. */
-    protected PrintWriter out;
-
-    /** Canonical output. */
-    protected boolean canonical;
-
-    //
-    // Constructors
-    //
-
-    /** Default constructor. */
-    public SAXWriter(boolean canonical) throws UnsupportedEncodingException {
-        this(null, canonical);
-    }
-
-    protected SAXWriter(String encoding, boolean canonical) throws UnsupportedEncodingException {
-
-        if (encoding == null) {
-            encoding = "UTF8";
-        }
-
-        out = new PrintWriter(new OutputStreamWriter(System.out, encoding));
-        this.canonical = canonical;
-
-    } // <init>(String,boolean)
-
-    //
-    // Public static methods
-    //
-
-    /** Prints the output from the SAX callbacks. */
-    public static void print(String parserName, String uri, boolean canonical) {
-
-        try {
-            HandlerBase handler = new SAXWriter(canonical);
-
-            Parser parser = ParserFactory.makeParser(parserName);
-
-
-            if ( parser instanceof XMLReader ){
-                ((XMLReader)parser).setFeature( "http://xml.org/sax/features/validation", 
-                                                setValidation);
-                ((XMLReader)parser).setFeature( "http://xml.org/sax/features/namespaces",
-                                                setNameSpaces );
-                ((XMLReader)parser).setFeature( "http://apache.org/xml/features/validation/schema",
-                                                setSchemaSupport );
-
-            }
-
-
-
-
-            parser.setDocumentHandler(handler);
-            parser.setErrorHandler(handler);
-            parser.parse(uri);
-        } catch (Exception e) {
-            e.printStackTrace(System.err);
-        }
-
-    } // print(String,String,boolean)
-
-    //
-    // DocumentHandler methods
-    //
-
-    /** Processing instruction. */
-    public void processingInstruction(String target, String data) {
-
-        out.print("<?");
-        out.print(target);
-        if (data != null && data.length() > 0) {
-            out.print(' ');
-            out.print(data);
-        }
-        out.print("?>");
-
-    } // processingInstruction(String,String)
-
-    /** Start document. */
-    public void startDocument() {
-
-        if (!canonical) {
-            out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-        }
-
-    } // startDocument()
-
-    /** Start element. */
-    public void startElement(String name, AttributeList attrs) {
-
-        out.print('<');
-        out.print(name);
-        if (attrs != null) {
-            attrs = sortAttributes(attrs);
-            int len = attrs.getLength();
-            for (int i = 0; i < len; i++) {
-                out.print(' ');
-                out.print(attrs.getName(i));
-                out.print("=\"");
-                out.print(normalize(attrs.getValue(i)));
-                out.print('"');
-            }
-        }
-        out.print('>');
-
-    } // startElement(String,AttributeList)
-
-    /** Characters. */
-    public void characters(char ch[], int start, int length) {
-
-        out.print(normalize(new String(ch, start, length)));
-
-    } // characters(char[],int,int);
-
-    /** Ignorable whitespace. */
-    public void ignorableWhitespace(char ch[], int start, int length) {
-
-        characters(ch, start, length);
-
-    } // ignorableWhitespace(char[],int,int);
-
-    /** End element. */
-    public void endElement(String name) {
-
-        out.print("</");
-        out.print(name);
-        out.print('>');
-
-    } // endElement(String)
-
-    /** End document. */
-    public void endDocument() {
-
-        out.flush();
-
-    } // endDocument()
-
-    //
-    // ErrorHandler methods
-    //
-
-    /** Warning. */
-    public void warning(SAXParseException ex) {
-        System.err.println("[Warning] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-    }
-
-    /** Error. */
-    public void error(SAXParseException ex) {
-        System.err.println("[Error] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-    }
-
-    /** Fatal error. */
-    public void fatalError(SAXParseException ex) throws SAXException {
-        System.err.println("[Fatal Error] "+
-                           getLocationString(ex)+": "+
-                           ex.getMessage());
-        throw ex;
-    }
-
-    /** Returns a string of the location. */
-    private String getLocationString(SAXParseException ex) {
-        StringBuffer str = new StringBuffer();
-
-        String systemId = ex.getSystemId();
-        if (systemId != null) {
-            int index = systemId.lastIndexOf('/');
-            if (index != -1)
-                systemId = systemId.substring(index + 1);
-            str.append(systemId);
-        }
-        str.append(':');
-        str.append(ex.getLineNumber());
-        str.append(':');
-        str.append(ex.getColumnNumber());
-
-        return str.toString();
-
-    } // getLocationString(SAXParseException):String
-
-    //
-    // Protected static methods
-    //
-
-    /** Normalizes the given string. */
-    protected String normalize(String s) {
-        StringBuffer str = new StringBuffer();
-
-        int len = (s != null) ? s.length() : 0;
-        for (int i = 0; i < len; i++) {
-            char ch = s.charAt(i);
-            switch (ch) {
-            case '<': {
-                    str.append("&lt;");
-                    break;
-                }
-            case '>': {
-                    str.append("&gt;");
-                    break;
-                }
-            case '&': {
-                    str.append("&amp;");
-                    break;
-                }
-            case '"': {
-                    str.append("&quot;");
-                    break;
-                }
-            case '\r':
-            case '\n': {
-                    if (canonical) {
-                        str.append("&#");
-                        str.append(Integer.toString(ch));
-                        str.append(';');
-                        break;
-                    }
-                    // else, default append char
-                }
-            default: {
-                    str.append(ch);
-                }
-            }
-        }
-
-        return str.toString();
-
-    } // normalize(String):String
-
-    /** Returns a sorted list of attributes. */
-    protected AttributeList sortAttributes(AttributeList attrs) {
-
-        AttributeListImpl attributes = new AttributeListImpl();
-        int len = (attrs != null) ? attrs.getLength() : 0;
-        for (int i = 0; i < len; i++) {
-            String name = attrs.getName(i);
-            int count = attributes.getLength();
-            int j = 0;
-            while (j < count) {
-                if (name.compareTo(attributes.getName(j)) < 0) {
-                    break;
-                }
-                j++;
-            }
-            attributes.insertAttributeAt(j, name, attrs.getType(i), 
-                                         attrs.getValue(i));
-        }
-
-        return attributes;
-
-    } // sortAttributes(AttributeList):AttributeList
-
-    //
-    // Main
-    //
-
-    /** Main program entry point. */
-    public static void main(String argv[]) {
-        ///
-        Arguments argopt = new Arguments();
-
-        argopt.setUsage( new String[] {
-                             "usage: java sax.SAXWriter (options) uri ...","",
-                             "options:",
-                             "  -n | -N  Turn on/off namespace [default=on]",
-                             "  -v | -V  Turn on/off validation [default=off]",
-                             "  -s | -S  Turn on/off Schema support [default=on]",
-                             "  -c       Canonical XML output.",
-                             "  -h       This help screen."} );
-
-
-
-
-        // is there anything to do?
-        if (argv.length == 0) {
-            argopt.printUsage();
-            System.exit(1);
-        }
-
-        // vars
-        boolean canonical  = false;
-        String  parserName = DEFAULT_PARSER_NAME;
-
-
-        argopt.parseArgumentTokens(argv, new char[] { 'p'} );
-
-        int   c;
-        String arg = null; 
-        while ( ( arg =  argopt.getlistFiles() ) != null ) {
-
-            outer:
-            while ( (c =  argopt.getArguments()) != -1 ){
-                switch (c) {
-                case 'c':
-                    canonical     = true;
-                    break;
-                case 'C':
-                    canonical     = false;
-                    break;
-                case 'v':
-                    setValidation = true;
-                    break;
-                case 'V':
-                    setValidation = false;
-                    break;
-                case 'N':
-                    setNameSpaces = false;
-                    break;
-                case 'n':
-                    setNameSpaces = true;
-                    break;
-                case 'p':
-                    parserName = argopt.getStringParameter();
-                    break;
-                case 's':
-                    setSchemaSupport = true;
-                    break;
-                case 'S':
-                    setSchemaSupport = false;
-                    break;
-                case '?':
-                case 'h':
-                case '-':
-                    argopt.printUsage();
-                    System.exit(1);
-                    break;
-                case -1:
-                    break outer;
-                default:
-                    break;
-                }
-            }
-            // print 
-            System.err.println(arg+':');
-            print(parserName, arg, canonical);
-        }
-    } // main(String[])
-
-} // class SAXWriter
diff --git a/samples/sax/helpers/AttributeListImpl.java b/samples/sax/helpers/AttributeListImpl.java
deleted file mode 100644
index fc5a483..0000000
--- a/samples/sax/helpers/AttributeListImpl.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package sax.helpers;
-                    
-import org.xml.sax.AttributeList;
-
-/**
- * An AttributeList implementation that can perform more operations
- * than the attribute list helper supplied with the standard SAX
- * distribution.
- */
-public class AttributeListImpl
-    implements AttributeList {
-
-    //
-    // Data
-    //
-
-    /** Head node. */
-    private ListNode head;
-
-    /** Tail node. */
-    private ListNode tail;
-
-    /** Length. */
-    private int length;
-
-    //
-    // AttributeList methods
-    //
-
-    /** Returns the number of attributes. */
-    public int getLength() {
-        return length;
-    }
-
-    /** Returns the attribute name by index. */
-    public String getName(int index) {
-
-        ListNode node = getNodeAt(index);
-        return (node != null) ? node.name : null;
-
-    } // getName(int):String
-
-    /** Returns the attribute type by index. */
-    public String getType(int index) {
-
-        ListNode node = getNodeAt(index);
-        return (node != null) ? node.type : null;
-
-    } // getType(int):String
-
-    /** Returns the attribute value by index. */
-    public String getValue(int index) {
-
-        ListNode node = getNodeAt(index);
-        return (node != null) ? node.value : null;
-
-    } // getType(int):String
-
-    /** Returns the attribute type by name. */
-    public String getType(String name) {
-
-        ListNode node = getNodeAt(name);
-        return (node != null) ? node.type : null;
-
-    } // getType(int):String
-
-    /** Returns the attribute value by name. */
-    public String getValue(String name) {
-
-        ListNode node = getNodeAt(name);
-        return (node != null) ? node.value : null;
-
-    } // getType(int):String
-
-    //
-    // Public methods
-    //
-
-    /** Adds an attribute. */
-    public void addAttribute(String name, String type, String value) {
-
-        ListNode node = new ListNode(name, type, value);
-        if (length == 0) {
-            head = node;
-        }
-        else {
-            tail.next = node;
-        }
-        tail = node;
-        length++;
-
-    } // addAttribute(String,String,String)
-
-    /** Inserts an attribute. */
-    public void insertAttributeAt(int index, 
-                                  String name, String type, String value) {
-
-        // if list is empty, add attribute
-        if (length == 0 || index >= length) {
-            addAttribute(name, type, value);
-            return;
-        }
-
-        // insert at beginning of list
-        ListNode node = new ListNode(name, type, value);
-        if (index < 1) {
-            node.next = head;
-            head = node;
-        }
-        else {
-            ListNode prev = getNodeAt(index - 1);
-            node.next = prev.next;
-            prev.next = node;
-        }
-        length++;
-
-    } // addAttribute(String,String,String)
-
-    /** Removes an attribute. */
-    public void removeAttributeAt(int index) {
-
-        if (length == 0) {
-            return;
-        }
-
-        if (index == 0) {
-            head = head.next;
-            if (head == null) {
-                tail = null;
-            }
-            length--;
-        }
-        else {
-            ListNode prev = getNodeAt(index - 1);
-            ListNode node = getNodeAt(index);
-            if (node != null) {
-                prev.next = node.next;
-                if (node == tail) {
-                    tail = prev;
-                }
-                length--;
-            }
-        }
-
-    } // removeAttributeAt(int)
-
-    //
-    // Private methods
-    //
-
-    /** Returns the node at the specified index. */
-    private ListNode getNodeAt(int i) {
-
-        for (ListNode place = head; place != null; place = place.next) {
-            if (--i == -1) {
-                return place;
-            }
-        }
-
-        return null;
-
-    } // getNodeAt(int):ListNode
-
-    /** Returns the first node with the specified name. */
-    private ListNode getNodeAt(String name) {
-
-        if (name != null) {
-            for (ListNode place = head; place != null; place = place.next) {
-                if (place.name.equals(name)) {
-                    return place;
-                }
-            }
-        }
-
-        return null;
-
-    } // getNodeAt(int):ListNode
-
-    //
-    // Object methods
-    //
-
-    /** Returns a string representation of this object. */
-    public String toString() {
-        StringBuffer str = new StringBuffer();
-
-        str.append('[');
-        str.append("len=");
-        str.append(length);
-        str.append(", {");
-        for (ListNode place = head; place != null; place = place.next) {
-            str.append(place.name);
-            if (place.next != null) {
-                str.append(", ");
-            }
-        }
-        str.append("}]");
-
-        return str.toString();
-
-    } // toString():String
-
-    //
-    // Classes
-    //
-
-    /**
-     * An attribute node.
-     */
-    static class ListNode {
-
-        //
-        // Data
-        //
-
-        /** Attribute name. */
-        public String name;
-
-        /** Attribute type. */
-        public String type;
-
-        /** Attribute value. */
-        public String value;
-
-        /** Next node. */
-        public ListNode next;
-
-        //
-        // Constructors
-        //
-
-        /** Default constructor. */
-        public ListNode(String name, String type, String value) {
-            this.name  = name;
-            this.type  = type;
-            this.value = value;
-        }
-
-    } // class ListNode
-
-} // class AttributeListImpl
diff --git a/samples/sax/helpers/AttributesImpl.java b/samples/sax/helpers/AttributesImpl.java
deleted file mode 100644
index 690373e..0000000
--- a/samples/sax/helpers/AttributesImpl.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package sax.helpers;
-                    
-import org.xml.sax.Attributes;
-
-/**
- * An Attributes implementation that can perform more operations
- * than the attribute list helper supplied with the standard SAX2
- * distribution.
- */
-public class AttributesImpl
-    implements Attributes {
-
-    //
-    // Data
-    //
-
-    /** Head node. */
-    private ListNode head;
-
-    /** Tail node. */
-    private ListNode tail;
-
-    /** Length. */
-    private int length;
-
-    //
-    // Attributes methods
-    //
-
-    /** Returns the number of attributes. */
-    public int getLength() {
-        return length;
-    }
-
-    /** Returns the index of the specified attribute. */
-    public int getIndex(String raw) {
-        ListNode place = head;
-        int index = 0;
-        while (place != null) {
-            if (place.raw.equals(raw)) {
-                return index;
-            }
-            index++;
-            place = place.next;
-        }
-        return -1;
-    }
-
-    /** Returns the index of the specified attribute. */
-    public int getIndex(String uri, String local) {
-        ListNode place = head;
-        int index = 0;
-        while (place != null) {
-            if (place.uri.equals(uri) && place.local.equals(local)) {
-                return index;
-            }
-            index++;
-            place = place.next;
-        }
-        return -1;
-    }
-
-    /** Returns the attribute URI by index. */
-    public String getURI(int index) {
-
-        ListNode node = getListNodeAt(index);
-        return node != null ? node.uri : null;
-
-    } // getURI(int):String
-
-    /** Returns the attribute local name by index. */
-    public String getLocalName(int index) {
-
-        ListNode node = getListNodeAt(index);
-        return node != null ? node.local : null;
-
-    } // getLocalName(int):String
-
-    /** Returns the attribute raw name by index. */
-    public String getQName(int index) {
-
-        ListNode node = getListNodeAt(index);
-        return node != null ? node.raw : null;
-
-    } // getQName(int):String
-
-    /** Returns the attribute type by index. */
-    public String getType(int index) {
-
-        ListNode node = getListNodeAt(index);
-        return (node != null) ? node.type : null;
-
-    } // getType(int):String
-
-    /** Returns the attribute type by uri and local. */
-    public String getType(String uri, String local) {
-
-        ListNode node = getListNode(uri, local);
-        return (node != null) ? node.type : null;
-
-    } // getType(String,String):String
-
-    /** Returns the attribute type by raw name. */
-    public String getType(String raw) {
-
-        ListNode node = getListNode(raw);
-        return (node != null) ? node.type : null;
-
-    } // getType(String):String
-
-    /** Returns the attribute value by index. */
-    public String getValue(int index) {
-
-        ListNode node = getListNodeAt(index);
-        return (node != null) ? node.value : null;
-
-    } // getType(int):String
-
-    /** Returns the attribute value by uri and local. */
-    public String getValue(String uri, String local) {
-
-        ListNode node = getListNode(uri, local);
-        return (node != null) ? node.value : null;
-
-    } // getType(String):String
-
-    /** Returns the attribute value by raw name. */
-    public String getValue(String raw) {
-
-        ListNode node = getListNode(raw);
-        return (node != null) ? node.value : null;
-
-    } // getType(String):String
-
-    //
-    // Public methods
-    //
-
-    /** Adds an attribute. */
-    public void addAttribute(String raw, String type, String value) {
-        addAttribute(null, null, raw, type, value);
-    }
-
-    /** Adds an attribute. */
-    public void addAttribute(String uri, String local, String raw, 
-                             String type, String value) {
-
-        ListNode node = new ListNode(uri, local, raw, type, value);
-        if (length == 0) {
-            head = node;
-        }
-        else {
-            tail.next = node;
-        }
-        tail = node;
-        length++;
-
-    } // addAttribute(String,StringString,String,String)
-
-    /** Inserts an attribute. */
-    public void insertAttributeAt(int index, 
-                                  String raw, String type, String value) {
-        insertAttributeAt(index, null, null, raw, type, value);
-    }
-
-    /** Inserts an attribute. */
-    public void insertAttributeAt(int index, 
-                                  String uri, String local, String raw, 
-                                  String type, String value) {
-
-        // if list is empty, add attribute
-        if (length == 0 || index >= length) {
-            addAttribute(uri, local, raw, type, value);
-            return;
-        }
-
-        // insert at beginning of list
-        ListNode node = new ListNode(uri, local, raw, type, value);
-        if (index < 1) {
-            node.next = head;
-            head = node;
-        }
-        else {
-            ListNode prev = getListNodeAt(index - 1);
-            node.next = prev.next;
-            prev.next = node;
-        }
-        length++;
-
-    } // insertAttributeAt(int,String,String,String,String,String)
-
-    /** Removes an attribute. */
-    public void removeAttributeAt(int index) {
-
-        if (length == 0) {
-            return;
-        }
-
-        if (index == 0) {
-            head = head.next;
-            if (head == null) {
-                tail = null;
-            }
-            length--;
-        }
-        else {
-            ListNode prev = getListNodeAt(index - 1);
-            ListNode node = getListNodeAt(index);
-            if (node != null) {
-                prev.next = node.next;
-                if (node == tail) {
-                    tail = prev;
-                }
-                length--;
-            }
-        }
-
-    } // removeAttributeAt(int)
-
-    /** Removes the specified attribute. */
-    public void removeAttribute(String raw) {
-        removeAttributeAt(getIndex(raw));
-    }
-
-    /** Removes the specified attribute. */
-    public void removeAttribute(String uri, String local) {
-        removeAttributeAt(getIndex(uri, local));
-    }
-
-    //
-    // Private methods
-    //
-
-    /** Returns the node at the specified index. */
-    private ListNode getListNodeAt(int i) {
-
-        for (ListNode place = head; place != null; place = place.next) {
-            if (--i == -1) {
-                return place;
-            }
-        }
-
-        return null;
-
-    } // getListNodeAt(int):ListNode
-
-    /** Returns the first node with the specified uri and local. */
-    public ListNode getListNode(String uri, String local) {
-
-        if (uri != null && local != null) {
-            ListNode place = head;
-            while (place != null) {
-                if (place.uri != null && place.local != null &&
-                    place.uri.equals(uri) && place.local.equals(local)) {
-                    return place;
-                }
-                place = place.next;
-            }
-        }
-        return null;
-
-    } // getListNode(String,String):ListNode
-    
-    /** Returns the first node with the specified raw name. */
-    private ListNode getListNode(String raw) {
-
-        if (raw != null) {
-            for (ListNode place = head; place != null; place = place.next) {
-                if (place.raw != null && place.raw.equals(raw)) {
-                    return place;
-                }
-            }
-        }
-
-        return null;
-
-    } // getListNode(String):ListNode
-
-    //
-    // Object methods
-    //
-
-    /** Returns a string representation of this object. */
-    public String toString() {
-        StringBuffer str = new StringBuffer();
-
-        str.append('[');
-        str.append("len=");
-        str.append(length);
-        str.append(", {");
-        for (ListNode place = head; place != null; place = place.next) {
-            str.append(place.toString());
-            if (place.next != null) {
-                str.append(", ");
-            }
-        }
-        str.append("}]");
-
-        return str.toString();
-
-    } // toString():String
-
-    //
-    // Classes
-    //
-
-    /**
-     * An attribute node.
-     */
-    static class ListNode {
-
-        //
-        // Data
-        //
-
-        /** Attribute uri. */
-        public String uri;
-
-        /** Attribute local. */
-        public String local;
-
-        /** Attribute raw. */
-        public String raw;
-
-        /** Attribute type. */
-        public String type;
-
-        /** Attribute value. */
-        public String value;
-
-        /** Next node. */
-        public ListNode next;
-
-        //
-        // Constructors
-        //
-
-        /** Constructs a list node. */
-        public ListNode(String uri, String local, String raw, 
-                        String type, String value) {
-
-            this.uri   = uri;
-            this.local = local;
-            this.raw   = raw;
-            this.type  = type;
-            this.value = value;
-
-        } // <init>(String,String,String,String,String)
-
-        //
-        // Object methods
-        //
-
-        /** Returns string representation of this object. */
-        public String toString() {
-            return raw != null ? raw : local;
-        }
-
-    } // class ListNode
-
-} // class AttributesImpl
diff --git a/samples/sax/helpers/Makefile b/samples/sax/helpers/Makefile
deleted file mode 100644
index d8f2480..0000000
--- a/samples/sax/helpers/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# Makefile for directory ./sax/helpers
-
-TARGETS=\
-	AttributesImpl.class\
-	AttributeListImpl.class
-
-DIRS = 
-
-TOP = ../../..
-include $(TOP)/src/Makefile.incl
diff --git a/samples/ui/DOMParserSaveEncoding.java b/samples/ui/DOMParserSaveEncoding.java
deleted file mode 100644
index 01cc7a1..0000000
--- a/samples/ui/DOMParserSaveEncoding.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package ui;
-import org.xml.sax.InputSource;
-import org.w3c.dom.Attr;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.apache.xerces.readers.MIME2Java;
-import org.apache.xerces.parsers.DOMParser;
-
-    /**
-     *  The DOMParserSaveEncoding class extends DOMParser. It also provides
-     *  the Java Encoding of the XML document by overriding the startDocument method 
-     *  and providing a way to capture the MIME encoding from the XML document which
-     *  in turn is converted to the Java Encoding by the internal MIME2Java class.
-     *   
-     */
-
-  
-public class DOMParserSaveEncoding extends DOMParser
-  {
-   String _mimeEncoding = "DEFAULT";//Default  MIME so we check the file.encoding
-   private void setMimeEncoding( String encoding ) {
-      _mimeEncoding = encoding;
-   }
-   private String getMimeEncoding() {
-      return (_mimeEncoding);
-   }
-   public String getJavaEncoding() {
-      String javaEncoding = null;
-      String mimeEncoding = getMimeEncoding();
-
-      if( mimeEncoding != null )
-      {
-      if( mimeEncoding.equals( "DEFAULT" ) )
-         javaEncoding = System.getProperty( "file.encoding" );
-      else if( ( javaEncoding = MIME2Java.convert( mimeEncoding ) ) == null )
-         javaEncoding = "UTF8";      // We always return an encoding.
-      }
-
-      if( javaEncoding == null )  // Should never return null
-         javaEncoding = "UTF8";
-
-      return (javaEncoding);
-   }
-   public void startDocument( int versionIndex, int encodingIndex, int standAloneIndex ) {
-      String encoding = null;
-      if ( encodingIndex != -1 ) {
-         encoding            = fStringPool.toString( encodingIndex );
-         setMimeEncoding( encoding );
-      }
- //     super.startDocument( versionIndex,  encodingIndex, standAloneIndex );//passes control to superclass
-      super.startDocument();
-   }
-
-  }
-    
diff --git a/samples/ui/DOMTree.java b/samples/ui/DOMTree.java
deleted file mode 100644
index a502dac..0000000
--- a/samples/ui/DOMTree.java
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package ui;
-
-import java.io.Serializable;
-import javax.swing.JTree;
-import javax.swing.event.TreeModelEvent;
-import javax.swing.event.TreeModelListener;
-import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.DefaultMutableTreeNode;
-import javax.swing.tree.MutableTreeNode;
-import javax.swing.tree.TreeNode;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.util.Hashtable;
-
-/**
- * Displays a DOM document in a tree control.
- *
- * @author  Andy Clark, IBM
- * @version
- */
-public class DOMTree
-    extends JTree 
-    {
-
-    //
-    // Constructors
-    //
-
-    /** Default constructor. */
-    public DOMTree() {
-        this(null);
-        }
-
-    /** Constructs a tree with the specified document. */
-    public DOMTree(Document document) {
-        super(new Model());
-
-        // set tree properties
-        setRootVisible(false);
-
-        // set properties
-        setDocument(document);
-
-        } // <init>()
-
-    //
-    // Public methods
-    //
-
-    /** Sets the document. */
-    public void setDocument(Document document) {
-        ((Model)getModel()).setDocument(document);
-        expandRow(0);
-        }
-
-    /** Returns the document. */
-    public Document getDocument() {
-        return ((Model)getModel()).getDocument();
-        }
-
-    /** get the org.w3c.Node for a MutableTreeNode. */
-    public Node getNode(Object treeNode) {
-        return ((Model)getModel()).getNode(treeNode);
-    }
-
-    //
-    // Classes
-    //
-
-    /**
-     * DOM tree model.
-     *
-     * @author  Andy Clark, IBM
-     * @version
-     */
-    static class Model 
-        extends DefaultTreeModel
-        implements Serializable
-        {
-
-        //
-        // Data
-        //
-
-        /** Document. */
-        private Document document;
-        /** Node Map. */
-        private Hashtable nodeMap = new Hashtable();
-        
-
-        //
-        // Constructors
-        //
-
-        /** Default constructor. */
-        public Model() {
-            this(null);
-            }
-
-        /** Constructs a model from the specified document. */
-        public Model(Document document) {
-            super(new DefaultMutableTreeNode());
-            setDocument(document);
-            }
-
-        //
-        // Public methods
-        //
-
-        /** Sets the document. */
-        public synchronized void setDocument(Document document) {
-
-            // save document
-            this.document = document;
-
-            // clear tree and re-populate
-            ((DefaultMutableTreeNode)getRoot()).removeAllChildren();
-            nodeMap.clear();
-            buildTree();
-            fireTreeStructureChanged(this, new Object[] { getRoot() }, new int[0], new Object[0]);
-
-            } // setDocument(Document)
-
-        /** Returns the document. */
-        public Document getDocument() {
-            return document;
-            }
-
-        /** get the org.w3c.Node for a MutableTreeNode. */
-        public Node getNode(Object treeNode) {
-            return (Node)nodeMap.get(treeNode);
-        }
-
-        //
-        // Private methods
-        //
-
-        /** Builds the tree. */
-        private void buildTree() {
-            
-            // is there anything to do?
-            if (document == null) { return; }
-
-            // iterate over children of this node
-            NodeList nodes = document.getChildNodes();
-            int len = (nodes != null) ? nodes.getLength() : 0;
-            MutableTreeNode root = (MutableTreeNode)getRoot();
-            for (int i = 0; i < len; i++) {
-                Node node = nodes.item(i);
-                switch (node.getNodeType()) {
-                    case Node.DOCUMENT_NODE: {
-                        root = insertDocumentNode(node, root);
-                        break;
-                        }
-
-                    case Node.ELEMENT_NODE: {
-                        insertElementNode(node, root);
-                        break;
-                        }
-
-                    default: // ignore
-
-                    } // switch
-
-                } // for 
-
-            } // buildTree()
-
-        /** Inserts a node and returns a reference to the new node. */
-        private MutableTreeNode insertNode(String what, MutableTreeNode where) {
-
-            MutableTreeNode node = new DefaultMutableTreeNode(what);
-            insertNodeInto(node, where, where.getChildCount());
-            return node;
-
-            } // insertNode(Node,MutableTreeNode):MutableTreeNode
-            
-        /** Inserts the document node. */
-        private MutableTreeNode insertDocumentNode(Node what, MutableTreeNode where) {
-            MutableTreeNode treeNode = insertNode("<"+what.getNodeName()+'>', where);
-            nodeMap.put(treeNode, what);
-            return treeNode;
-            }
-
-        /** Inserts an element node. */
-        private MutableTreeNode insertElementNode(Node what, MutableTreeNode where) {
-
-            // build up name
-            StringBuffer name = new StringBuffer();
-            name.append('<');
-            name.append(what.getNodeName());
-            NamedNodeMap attrs = what.getAttributes();
-            int attrCount = (attrs != null) ? attrs.getLength() : 0;
-            for (int i = 0; i < attrCount; i++) {
-                Node attr = attrs.item(i);
-                name.append(' ');
-                name.append(attr.getNodeName());
-                name.append("=\"");
-                name.append(attr.getNodeValue());
-                name.append('"');
-                }
-            name.append('>');
-
-            // insert element node
-            
-            MutableTreeNode element = insertNode(name.toString(), where);
-            nodeMap.put(element, what);
-            
-            // gather up attributes and children nodes
-            NodeList children = what.getChildNodes();
-            int len = (children != null) ? children.getLength() : 0;
-            for (int i = 0; i < len; i++) {
-                Node node = children.item(i);
-                switch (node.getNodeType()) {
-                    case Node.CDATA_SECTION_NODE: { 
-                       insertCDataSectionNode( node, element ); //Add a Section Node
-                       break;
-                      }
-                    case Node.TEXT_NODE: {
-                        insertTextNode(node, element);
-                        break;
-                        }
-                    case Node.ELEMENT_NODE: {
-                        insertElementNode(node, element);
-                        break;
-                        }
-                    }
-                }
-
-            return element;
-
-            } // insertElementNode(Node,MutableTreeNode):MutableTreeNode
-
-        /** Inserts a text node. */
-        private MutableTreeNode insertTextNode(Node what, MutableTreeNode where) {
-            String value = what.getNodeValue().trim();
-            if (value.length() > 0) {
-                MutableTreeNode treeNode = insertNode(value, where);
-                nodeMap.put(treeNode, what);            
-                return treeNode;
-                }
-            return null;
-            }
-
-        
-      /** Inserts a CData Section Node. */
-      private MutableTreeNode insertCDataSectionNode(Node what, MutableTreeNode where) {
-         StringBuffer CSectionBfr = new StringBuffer();         
-         //--- optional --- CSectionBfr.append( "<![CDATA[" );
-         CSectionBfr.append( what.getNodeValue() );
-         //--- optional --- CSectionBfr.append( "]]>" );
-         if (CSectionBfr.length() > 0) {
-            MutableTreeNode treeNode = insertNode(CSectionBfr.toString(), where);
-            nodeMap.put(treeNode, what);            
-            return treeNode;
-            }
-         return null;
-         }
-
-
-      } // class Model
-
-
-
-    } // class DOMTree
diff --git a/samples/ui/DOMTreeFull.java b/samples/ui/DOMTreeFull.java
deleted file mode 100644
index e14a656..0000000
--- a/samples/ui/DOMTreeFull.java
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package ui;
-
-
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import javax.swing.JTree;
-import javax.swing.event.TreeModelEvent;
-import javax.swing.event.TreeModelListener;
-import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.DefaultMutableTreeNode;
-import javax.swing.tree.MutableTreeNode;
-import javax.swing.tree.TreeNode;
-
-import org.w3c.dom.*;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.util.Hashtable;
-import java.util.Enumeration;
-
-/**
- *  DOMTree class to enter every DOM node into a Swing JTree tree.
- *  The forward and backward mappings between Nodes to TreeNodes are kept.
- *
- */
-public class DOMTreeFull
-    extends JTree 
-    {
-
-    //
-    // Constructors
-    //
-
-    /** Default constructor. */
-    public DOMTreeFull() {
-        this(null);
-        }
-
-    /** Constructs a tree with the specified document. */
-    public DOMTreeFull(Node root) {
-        super(new Model());
-
-        // set tree properties
-        setRootVisible(false);
-
-        // set properties
-        setRootNode(root);
-
-        } // <init>()
-
-    //
-    // Public methods
-    //
-
-    /** Sets the root. */
-    public void setRootNode(Node root) {
-        ((Model)getModel()).setRootNode(root);
-        expandRow(0);
-        }
-
-    /** Returns the root. */
-    public Node getRootNode() {
-        return ((Model)getModel()).getRootNode();
-        }
-
-    /** get the org.w3c.Node for a MutableTreeNode. */
-    public Node getNode(Object treeNode) {
-        return ((Model)getModel()).getNode(treeNode);
-    }
-
-    /** get the TreeNode for the org.w3c.Node */
-    public TreeNode getTreeNode(Object node) {
-        return ((Model)getModel()).getTreeNode(node);
-    }
-
-    //
-    // Classes
-    //
-
-    /**
-     * DOM tree model.
-     *
-     */
-    public static class Model 
-        extends DefaultTreeModel
-        implements Serializable
-        {
-
-        //
-        // Data
-        //
-
-        /** Root. */
-        private Node root;
-        /** Node Map. */
-        private Hashtable nodeMap = new Hashtable();
-        /** Tree Node Map. */
-        private Hashtable treeNodeMap = new Hashtable();        
-
-        //
-        // Constructors
-        //
-
-        /** Default constructor. */
-        public Model() {
-            this(null);
-            }
-
-        /** Constructs a model from the specified root. */
-        public Model(Node node) {
-            super(new DefaultMutableTreeNode());
-            if (node!=null)
-            setRootNode(node);
-            }
-
-        //
-        // Public methods
-        //
-
-        /** Sets the root. */
-        public synchronized void setRootNode(Node root) {
-            
-            // save root
-            this.root = root;
-
-            // clear tree and re-populate
-            DefaultMutableTreeNode where = (DefaultMutableTreeNode)getRoot();
-            where.removeAllChildren();
-            nodeMap.clear();
-            treeNodeMap.clear();
-
-            buildTree(root, where);
-            
-            fireTreeStructureChanged(this, new Object[] { getRoot() }, new int[0], new Object[0]);
-
-            } // setRootNode(Node)
-
-        /** Returns the root. */
-        public Node getRootNode() {
-            return root;
-            }
-
-        /** get the org.w3c.Node for a MutableTreeNode. */
-        public Node getNode(Object treeNode) {
-            return (Node)nodeMap.get(treeNode);
-        }
-        public Hashtable getAllNodes() {
-            return nodeMap;
-        }
-        /** get the org.w3c.Node for a MutableTreeNode. */
-        public TreeNode getTreeNode(Object node) {
-            Object object = treeNodeMap.get(node);
-            return (TreeNode)object;
-        }
-
-        //
-        // Private methods
-        //
-
-        /** Builds the tree. */
-        private void buildTree(Node node, MutableTreeNode where) {
-            
-            // is there anything to do?
-            if (node == null) { return; }
-
-            MutableTreeNode treeNode = insertNode(node, where);
-
-            // iterate over children of this node
-            NodeList nodes = node.getChildNodes();
-            int len = (nodes != null) ? nodes.getLength() : 0;
-            for (int i = 0; i < len; i++) {
-                Node child = nodes.item(i);
-                buildTree(child, treeNode);
-
-            }
-
-
-        } // buildTree()
-
-        /** Inserts a node and returns a reference to the new node. */
-        private MutableTreeNode insertNode(String what, MutableTreeNode where) {
-
-            MutableTreeNode node = new DefaultMutableTreeNode(what);
-            insertNodeInto(node, where, where.getChildCount());
-            return node;
-
-            } // insertNode(Node,MutableTreeNode):MutableTreeNode
-            
-
-        /** Inserts a text node. */
-        public MutableTreeNode insertNode(Node what, MutableTreeNode where) {
-                MutableTreeNode treeNode = insertNode(DOMTreeFull.toString(what), where);
-                nodeMap.put(treeNode, what); 
-                treeNodeMap.put(what, treeNode);
-                return treeNode;
-            }
-        } // class Model
-        
-        public static String whatArray[] = new String [] { 
-                "ALL",
-                "ELEMENT",
-                "ATTRIBUTE",
-                "TEXT",
-                "CDATA_SECTION",
-                "ENTITY_REFERENCE",
-                "ENTITY",
-                "PROCESSING_INSTRUCTION", 
-                "COMMENT", 
-                "DOCUMENT", 
-                "DOCUMENT_TYPE",
-                "DOCUMENT_FRAGMENT",
-                "NOTATION" 
-                };
-        //
-        // Public methods
-        //
-                
-        public static String toString(Node node) {
-            StringBuffer sb = new StringBuffer();
-                
-            // is there anything to do?
-            if (node == null) {
-                return "";
-            }
-
-            int type = node.getNodeType();
-            sb.append(whatArray[type]);
-            sb.append(" : ");
-            sb.append(node.getNodeName());
-            String value = node.getNodeValue();
-            if (value != null) {
-                sb.append(" Value: \"");
-                sb.append(value);
-                sb.append("\"");
-            }
-                    
-            switch (type) {
-                    
-                // document
-                case Node.DOCUMENT_NODE: {
-                    break;
-                }
-
-                // element with attributes
-                case Node.ELEMENT_NODE: {
-                    Attr attrs[] = sortAttributes(node.getAttributes());
-                    if (attrs.length > 0)
-                        sb.append(" ATTRS:");
-                    for (int i = 0; i < attrs.length; i++) {
-                        Attr attr = attrs[i];
-                            
-                        sb.append(' ');
-                        sb.append(attr.getNodeName());
-                        sb.append("=\"");
-                        sb.append(normalize(attr.getNodeValue()));
-                        sb.append('"');
-                    }
-                    sb.append('>');
-                    break;
-                }
-
-                // handle entity reference nodes
-                case Node.ENTITY_REFERENCE_NODE: {
-                    break;
-                }
-
-                // cdata sections
-                case Node.CDATA_SECTION_NODE: {
-                    break;
-                }
-
-                // text
-                case Node.TEXT_NODE: {
-                    break;
-                }
-
-                // processing instruction
-                case Node.PROCESSING_INSTRUCTION_NODE: {
-                    break;
-                }
-                    
-                // comment node 
-                case Node.COMMENT_NODE: {
-                    break;
-                }
-                // DOCTYPE node
-                case Node.DOCUMENT_TYPE_NODE: {
-                    break;
-                }
-                // Notation node
-                case Node.NOTATION_NODE: {
-                        sb.append("public:");
-                        String id = ((Notation)node).getPublicId();
-                        if (id == null) {
-                            sb.append("PUBLIC ");
-                            sb.append(id);
-                            sb.append(" ");
-                        }
-                        id = ((Notation)node).getSystemId();
-                        if (id == null) {
-                            sb.append("system: ");
-                            sb.append(id);
-                            sb.append(" ");
-                        }
-                    break;
-                }
-            }
-            return sb.toString();
-        }
-            
-        /** Normalizes the given string. */
-        static protected String normalize(String s) {
-            StringBuffer str = new StringBuffer();
-
-            int len = (s != null) ? s.length() : 0;
-            for (int i = 0; i < len; i++) {
-                char ch = s.charAt(i);
-                switch (ch) {
-                    case '<': {
-                        str.append("&lt;");
-                        break;
-                    }
-                    case '>': {
-                        str.append("&gt;");
-                        break;
-                    }
-                    case '&': {
-                        str.append("&amp;");
-                        break;
-                    }
-                    case '"': {
-                        str.append("&quot;");
-                        break;
-                    }
-                    case '\r':
-                    case '\n': 
-                    default: {
-                        str.append(ch);
-                    }
-                }
-            }
-
-            return str.toString();
-
-        } // normalize(String):String
-
-        /** Returns a sorted list of attributes. */
-        static protected Attr[] sortAttributes(NamedNodeMap attrs) {
-
-            int len = (attrs != null) ? attrs.getLength() : 0;
-            Attr array[] = new Attr[len];
-            for (int i = 0; i < len; i++) {
-                array[i] = (Attr)attrs.item(i);
-            }
-            for (int i = 0; i < len - 1; i++) {
-                String name  = array[i].getNodeName();
-                int    index = i;
-                for (int j = i + 1; j < len; j++) {
-                    String curName = array[j].getNodeName();
-                    if (curName.compareTo(name) < 0) {
-                        name  = curName;
-                        index = j;
-                    }
-                }
-                if (index != i) {
-                    Attr temp    = array[i];
-                    array[i]     = array[index];
-                    array[index] = temp;
-                }
-            }
-
-            return array;
-
-        } // sortAttributes(NamedNodeMap):Attr[]        
-
-    } // class DOMTreeFull
-
diff --git a/samples/ui/DefaultImages.java b/samples/ui/DefaultImages.java
deleted file mode 100644
index 54d6116..0000000
--- a/samples/ui/DefaultImages.java
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package ui;
-
-import java.awt.*;
-
-public class DefaultImages {
-
-    public static java.awt.Image createOpenFolderImage() {
-        byte data[] = {
-            (byte) 71, (byte) 73, (byte) 70, (byte) 56, (byte) 57, (byte) 97,
-            (byte) 18, (byte)  0, (byte) 15, (byte)  0, (byte)247, (byte)  0,
-            (byte)  0, (byte) 74, (byte) 99, (byte)123, (byte) 99, (byte) 99,
-            (byte) 99, (byte)156, (byte)156, (byte) 99, (byte)206, (byte)206,
-            (byte) 99, (byte)206, (byte)206, (byte)156, (byte)239, (byte)231,
-            (byte)115, (byte)247, (byte)239, (byte)132, (byte)247, (byte)247,
-            (byte)247, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte) 33, (byte)249, (byte)  4, (byte)  1, (byte)  0,
-            (byte)  0, (byte)  8, (byte)  0, (byte) 44, (byte)  0, (byte)  0,
-            (byte)  0, (byte)  0, (byte) 18, (byte)  0, (byte) 15, (byte)  0,
-            (byte) 64, (byte)  8, (byte)106, (byte)  0, (byte) 17, (byte)  8,
-            (byte) 28, (byte) 72, (byte)176, (byte) 32, (byte)193, (byte)  1,
-            (byte)  7, (byte) 12, (byte) 40, (byte) 92, (byte)200, (byte)112,
-            (byte) 64, (byte)  0, (byte)  1, (byte)  1, (byte)  6, (byte) 14,
-            (byte) 40, (byte) 64, (byte)177, (byte)162, (byte) 69, (byte)138,
-            (byte) 16, (byte) 15, (byte) 14, (byte)216, (byte)200, (byte)177,
-            (byte)227, (byte)198, (byte)136, (byte) 18, (byte) 45, (byte) 14,
-            (byte) 16, (byte) 96, (byte) 80, (byte)226, (byte)129, (byte)147,
-            (byte) 40, (byte) 83, (byte) 58, (byte) 20, (byte)144, (byte) 81,
-            (byte) 32, (byte) 66, (byte)134, (byte) 48, (byte) 13, (byte) 56,
-            (byte)  4, (byte) 89, (byte)178, (byte)166, (byte)193, (byte)142,
-            (byte) 36, (byte)109, (byte) 34, (byte)152, (byte)120, (byte)209,
-            (byte)227, (byte)200, (byte)131, (byte)  4, (byte)130, (byte) 10,
-            (byte) 29, (byte) 42, (byte)160, (byte) 64, (byte)203, (byte)151,
-            (byte) 49, (byte) 21, (byte)174, (byte)108, (byte)185, (byte) 51,
-            (byte) 97, (byte) 82, (byte)153, (byte) 15, (byte)105, (byte) 54,
-            (byte)125, (byte) 10, (byte) 85, (byte) 42, (byte)130, (byte)  0,
-            (byte) 88, (byte)179, (byte)106, (byte)205, (byte)138, (byte) 32,
-            (byte) 32, (byte)  0, (byte) 59
-            };
-
-        return java.awt.Toolkit.getDefaultToolkit().createImage(data);
-        }
-    public static java.awt.Image createClosedFolderImage() {
-        byte data[] = {
-            (byte) 71, (byte) 73, (byte) 70, (byte) 56, (byte) 57, (byte) 97,
-            (byte) 18, (byte)  0, (byte) 15, (byte)  0, (byte)247, (byte)  0,
-            (byte)  0, (byte) 99, (byte) 99, (byte) 99, (byte)156, (byte)156,
-            (byte) 99, (byte)206, (byte)206, (byte) 99, (byte)239, (byte)231,
-            (byte)115, (byte)247, (byte)239, (byte)132, (byte)247, (byte)247,
-            (byte)247, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255,
-            (byte)255, (byte) 33, (byte)249, (byte)  4, (byte)  1, (byte)  0,
-            (byte)  0, (byte)  6, (byte)  0, (byte) 44, (byte)  0, (byte)  0,
-            (byte)  0, (byte)  0, (byte) 18, (byte)  0, (byte) 15, (byte)  0,
-            (byte) 64, (byte)  8, (byte) 91, (byte)  0, (byte) 13, (byte)  8,
-            (byte) 28, (byte) 72, (byte)176, (byte) 32, (byte) 65, (byte)  1,
-            (byte)  5, (byte)  8, (byte) 40, (byte) 92, (byte)200, (byte) 80,
-            (byte) 97, (byte)  0, (byte)  0, (byte)  2, (byte) 17, (byte) 22,
-            (byte)152, (byte) 72, (byte)177, (byte)226, (byte)196, (byte)135,
-            (byte) 17, (byte)  5, (byte)104, (byte)220, (byte)200, (byte)113,
-            (byte) 35, (byte)198, (byte)136, (byte)  3, (byte) 66, (byte) 14,
-            (byte) 16, (byte) 16, (byte)192, (byte)224, (byte)193, (byte)132,
-            (byte) 13, (byte) 83, (byte)126, (byte) 68, (byte)152, (byte) 82,
-            (byte) 37, (byte) 68, (byte)147, (byte) 48, (byte) 13, (byte)114,
-            (byte) 44, (byte) 25, (byte)211, (byte) 64, (byte)199, (byte)155,
-            (byte) 30, (byte)  7, (byte)178, (byte)108, (byte)201, (byte)112,
-            (byte) 37, (byte) 74, (byte)158, (byte) 14, (byte) 95, (byte)238,
-            (byte)  4, (byte) 74, (byte)192, (byte) 39, (byte)209, (byte)160,
-            (byte)  2, (byte)  1, (byte) 40, (byte) 93, (byte)202, (byte)180,
-            (byte) 41, (byte)196, (byte)128, (byte)  0, (byte)  0, (byte) 59
-            };
-
-        return java.awt.Toolkit.getDefaultToolkit().createImage(data);
-        }
-    public static java.awt.Image createLeafImage() {
-        byte data[] = {
-            (byte) 71, (byte) 73, (byte) 70, (byte) 56, (byte) 57, (byte) 97,
-            (byte) 14, (byte)  0, (byte) 15, (byte)  0, (byte)247, (byte)  0,
-            (byte)  0, (byte)  0, (byte)  0, (byte)  0, (byte)  1, (byte)  1,
-            (byte)  1, (byte)  2, (byte)  2, (byte)  2, (byte)  3, (byte)  3,
-            (byte)  3, (byte)  4, (byte)  4, (byte)  4, (byte)  5, (byte)  5,
-            (byte)  5, (byte)  6, (byte)  6, (byte)  6, (byte)  7, (byte)  7,
-            (byte)  7, (byte)  8, (byte)  8, (byte)  8, (byte)  9, (byte)  9,
-            (byte)  9, (byte) 10, (byte) 10, (byte) 10, (byte) 11, (byte) 11,
-            (byte) 11, (byte) 12, (byte) 12, (byte) 12, (byte) 13, (byte) 13,
-            (byte) 13, (byte) 14, (byte) 14, (byte) 14, (byte) 15, (byte) 15,
-            (byte) 15, (byte) 16, (byte) 16, (byte) 16, (byte) 17, (byte) 17,
-            (byte) 17, (byte) 18, (byte) 18, (byte) 18, (byte) 19, (byte) 19,
-            (byte) 19, (byte) 20, (byte) 20, (byte) 20, (byte) 21, (byte) 21,
-            (byte) 21, (byte) 22, (byte) 22, (byte) 22, (byte) 23, (byte) 23,
-            (byte) 23, (byte) 24, (byte) 24, (byte) 24, (byte) 25, (byte) 25,
-            (byte) 25, (byte) 26, (byte) 26, (byte) 26, (byte) 27, (byte) 27,
-            (byte) 27, (byte) 28, (byte) 28, (byte) 28, (byte) 29, (byte) 29,
-            (byte) 29, (byte) 30, (byte) 30, (byte) 30, (byte) 31, (byte) 31,
-            (byte) 31, (byte) 32, (byte) 32, (byte) 32, (byte) 33, (byte) 33,
-            (byte) 33, (byte) 34, (byte) 34, (byte) 34, (byte) 35, (byte) 35,
-            (byte) 35, (byte) 36, (byte) 36, (byte) 36, (byte) 37, (byte) 37,
-            (byte) 37, (byte) 38, (byte) 38, (byte) 38, (byte) 39, (byte) 39,
-            (byte) 39, (byte) 40, (byte) 40, (byte) 40, (byte) 41, (byte) 41,
-            (byte) 41, (byte) 42, (byte) 42, (byte) 42, (byte) 43, (byte) 43,
-            (byte) 43, (byte) 44, (byte) 44, (byte) 44, (byte) 45, (byte) 45,
-            (byte) 45, (byte) 46, (byte) 46, (byte) 46, (byte) 47, (byte) 47,
-            (byte) 47, (byte) 48, (byte) 48, (byte) 48, (byte) 49, (byte) 49,
-            (byte) 49, (byte) 50, (byte) 50, (byte) 50, (byte) 51, (byte) 51,
-            (byte) 51, (byte) 52, (byte) 52, (byte) 52, (byte) 53, (byte) 53,
-            (byte) 53, (byte) 54, (byte) 54, (byte) 54, (byte) 55, (byte) 55,
-            (byte) 55, (byte) 56, (byte) 56, (byte) 56, (byte) 57, (byte) 57,
-            (byte) 57, (byte) 58, (byte) 58, (byte) 58, (byte) 59, (byte) 59,
-            (byte) 59, (byte) 60, (byte) 60, (byte) 60, (byte) 61, (byte) 61,
-            (byte) 61, (byte) 62, (byte) 62, (byte) 62, (byte) 63, (byte) 63,
-            (byte) 63, (byte) 64, (byte) 64, (byte) 64, (byte) 65, (byte) 65,
-            (byte) 65, (byte) 66, (byte) 66, (byte) 66, (byte) 67, (byte) 67,
-            (byte) 67, (byte) 68, (byte) 68, (byte) 68, (byte) 69, (byte) 69,
-            (byte) 69, (byte) 70, (byte) 70, (byte) 70, (byte) 71, (byte) 71,
-            (byte) 71, (byte) 72, (byte) 72, (byte) 72, (byte) 73, (byte) 73,
-            (byte) 73, (byte) 74, (byte) 74, (byte) 74, (byte) 75, (byte) 75,
-            (byte) 75, (byte) 76, (byte) 76, (byte) 76, (byte) 77, (byte) 77,
-            (byte) 77, (byte) 78, (byte) 78, (byte) 78, (byte) 79, (byte) 79,
-            (byte) 79, (byte) 80, (byte) 80, (byte) 80, (byte) 81, (byte) 81,
-            (byte) 81, (byte) 82, (byte) 82, (byte) 82, (byte) 83, (byte) 83,
-            (byte) 83, (byte) 84, (byte) 84, (byte) 84, (byte) 85, (byte) 85,
-            (byte) 85, (byte) 86, (byte) 86, (byte) 86, (byte) 87, (byte) 87,
-            (byte) 87, (byte) 88, (byte) 88, (byte) 88, (byte) 89, (byte) 89,
-            (byte) 89, (byte) 90, (byte) 90, (byte) 90, (byte) 91, (byte) 91,
-            (byte) 91, (byte) 92, (byte) 92, (byte) 92, (byte) 93, (byte) 93,
-            (byte) 93, (byte) 94, (byte) 94, (byte) 94, (byte) 95, (byte) 95,
-            (byte) 95, (byte) 96, (byte) 96, (byte) 96, (byte) 97, (byte) 97,
-            (byte) 97, (byte) 98, (byte) 98, (byte) 98, (byte) 99, (byte) 99,
-            (byte) 99, (byte)100, (byte)100, (byte)100, (byte)101, (byte)101,
-            (byte)101, (byte)102, (byte)102, (byte)102, (byte)103, (byte)103,
-            (byte)103, (byte)104, (byte)104, (byte)104, (byte)105, (byte)105,
-            (byte)105, (byte)106, (byte)106, (byte)106, (byte)107, (byte)107,
-            (byte)107, (byte)108, (byte)108, (byte)108, (byte)109, (byte)109,
-            (byte)109, (byte)110, (byte)110, (byte)110, (byte)111, (byte)111,
-            (byte)111, (byte)112, (byte)112, (byte)112, (byte)113, (byte)113,
-            (byte)113, (byte)114, (byte)114, (byte)114, (byte)115, (byte)115,
-            (byte)115, (byte)116, (byte)116, (byte)116, (byte)117, (byte)117,
-            (byte)117, (byte)118, (byte)118, (byte)118, (byte)119, (byte)119,
-            (byte)119, (byte)120, (byte)120, (byte)120, (byte)121, (byte)121,
-            (byte)121, (byte)122, (byte)122, (byte)122, (byte)123, (byte)123,
-            (byte)123, (byte)124, (byte)124, (byte)124, (byte)125, (byte)125,
-            (byte)125, (byte)126, (byte)126, (byte)126, (byte)127, (byte)127,
-            (byte)127, (byte)128, (byte)128, (byte)128, (byte)129, (byte)129,
-            (byte)129, (byte)130, (byte)130, (byte)130, (byte)131, (byte)131,
-            (byte)131, (byte)132, (byte)132, (byte)132, (byte)133, (byte)133,
-            (byte)133, (byte)134, (byte)134, (byte)134, (byte)135, (byte)135,
-            (byte)135, (byte)136, (byte)136, (byte)136, (byte)137, (byte)137,
-            (byte)137, (byte)138, (byte)138, (byte)138, (byte)139, (byte)139,
-            (byte)139, (byte)140, (byte)140, (byte)140, (byte)141, (byte)141,
-            (byte)141, (byte)142, (byte)142, (byte)142, (byte)143, (byte)143,
-            (byte)143, (byte)144, (byte)144, (byte)144, (byte)145, (byte)145,
-            (byte)145, (byte)146, (byte)146, (byte)146, (byte)147, (byte)147,
-            (byte)147, (byte)148, (byte)148, (byte)148, (byte)149, (byte)149,
-            (byte)149, (byte)150, (byte)150, (byte)150, (byte)151, (byte)151,
-            (byte)151, (byte)152, (byte)152, (byte)152, (byte)153, (byte)153,
-            (byte)153, (byte)154, (byte)154, (byte)154, (byte)155, (byte)155,
-            (byte)155, (byte)156, (byte)156, (byte)156, (byte)157, (byte)157,
-            (byte)157, (byte)158, (byte)158, (byte)158, (byte)159, (byte)159,
-            (byte)159, (byte)160, (byte)160, (byte)160, (byte)161, (byte)161,
-            (byte)161, (byte)162, (byte)162, (byte)162, (byte)163, (byte)163,
-            (byte)163, (byte)164, (byte)164, (byte)164, (byte)165, (byte)165,
-            (byte)165, (byte)166, (byte)166, (byte)166, (byte)167, (byte)167,
-            (byte)167, (byte)168, (byte)168, (byte)168, (byte)169, (byte)169,
-            (byte)169, (byte)170, (byte)170, (byte)170, (byte)171, (byte)171,
-            (byte)171, (byte)172, (byte)172, (byte)172, (byte)173, (byte)173,
-            (byte)173, (byte)174, (byte)174, (byte)174, (byte)175, (byte)175,
-            (byte)175, (byte)176, (byte)176, (byte)176, (byte)177, (byte)177,
-            (byte)177, (byte)178, (byte)178, (byte)178, (byte)179, (byte)179,
-            (byte)179, (byte)180, (byte)180, (byte)180, (byte)181, (byte)181,
-            (byte)181, (byte)182, (byte)182, (byte)182, (byte)183, (byte)183,
-            (byte)183, (byte)184, (byte)184, (byte)184, (byte)185, (byte)185,
-            (byte)185, (byte)186, (byte)186, (byte)186, (byte)187, (byte)187,
-            (byte)187, (byte)188, (byte)188, (byte)188, (byte)189, (byte)189,
-            (byte)189, (byte)190, (byte)190, (byte)190, (byte)191, (byte)191,
-            (byte)191, (byte)192, (byte)192, (byte)192, (byte)193, (byte)193,
-            (byte)193, (byte)194, (byte)194, (byte)194, (byte)195, (byte)195,
-            (byte)195, (byte)196, (byte)196, (byte)196, (byte)197, (byte)197,
-            (byte)197, (byte)198, (byte)198, (byte)198, (byte)199, (byte)199,
-            (byte)199, (byte)200, (byte)200, (byte)200, (byte)201, (byte)201,
-            (byte)201, (byte)202, (byte)202, (byte)202, (byte)203, (byte)203,
-            (byte)203, (byte)204, (byte)204, (byte)204, (byte)205, (byte)205,
-            (byte)205, (byte)206, (byte)206, (byte)206, (byte)207, (byte)207,
-            (byte)207, (byte)208, (byte)208, (byte)208, (byte)209, (byte)209,
-            (byte)209, (byte)210, (byte)210, (byte)210, (byte)211, (byte)211,
-            (byte)211, (byte)212, (byte)212, (byte)212, (byte)213, (byte)213,
-            (byte)213, (byte)214, (byte)214, (byte)214, (byte)215, (byte)215,
-            (byte)215, (byte)216, (byte)216, (byte)216, (byte)217, (byte)217,
-            (byte)217, (byte)218, (byte)218, (byte)218, (byte)219, (byte)219,
-            (byte)219, (byte)220, (byte)220, (byte)220, (byte)221, (byte)221,
-            (byte)221, (byte)222, (byte)222, (byte)222, (byte)223, (byte)223,
-            (byte)223, (byte)224, (byte)224, (byte)224, (byte)225, (byte)225,
-            (byte)225, (byte)226, (byte)226, (byte)226, (byte)227, (byte)227,
-            (byte)227, (byte)228, (byte)228, (byte)228, (byte)229, (byte)229,
-            (byte)229, (byte)230, (byte)230, (byte)230, (byte)231, (byte)231,
-            (byte)231, (byte)232, (byte)232, (byte)232, (byte)233, (byte)233,
-            (byte)233, (byte)234, (byte)234, (byte)234, (byte)235, (byte)235,
-            (byte)235, (byte)236, (byte)236, (byte)236, (byte)237, (byte)237,
-            (byte)237, (byte)238, (byte)238, (byte)238, (byte)239, (byte)239,
-            (byte)239, (byte)240, (byte)240, (byte)240, (byte)241, (byte)241,
-            (byte)241, (byte)242, (byte)242, (byte)242, (byte)243, (byte)243,
-            (byte)243, (byte)244, (byte)244, (byte)244, (byte)245, (byte)245,
-            (byte)245, (byte)246, (byte)246, (byte)246, (byte)247, (byte)247,
-            (byte)247, (byte)248, (byte)248, (byte)248, (byte)249, (byte)249,
-            (byte)249, (byte)250, (byte)250, (byte)250, (byte)251, (byte)251,
-            (byte)251, (byte)252, (byte)252, (byte)252, (byte)253, (byte)253,
-            (byte)253, (byte)254, (byte)254, (byte)254, (byte)255, (byte)255,
-            (byte)255, (byte) 33, (byte)249, (byte)  4, (byte)  1, (byte)  0,
-            (byte)  0, (byte) 87, (byte)  0, (byte) 44, (byte)  0, (byte)  0,
-            (byte)  0, (byte)  0, (byte) 14, (byte)  0, (byte) 15, (byte)  0,
-            (byte) 64, (byte)  8, (byte) 72, (byte)  0, (byte)  1, (byte)  8,
-            (byte) 28, (byte) 72, (byte) 16, (byte)192, (byte)149, (byte)131,
-            (byte)  0, (byte)254, (byte) 41, (byte) 92, (byte)200, (byte) 80,
-            (byte)161, (byte)192, (byte)134, (byte) 16, (byte)255, (byte) 61,
-            (byte)140, (byte)200, (byte)112, (byte) 98, (byte) 68, (byte)  0,
-            (byte)231, (byte)  8, (byte) 93, (byte) 73, (byte) 72, (byte)113,
-            (byte)161, (byte)197, (byte)142, (byte)  5, (byte) 67, (byte) 22,
-            (byte)  4, (byte)169, (byte)113, (byte)163, (byte) 66, (byte) 66,
-            (byte) 40, (byte) 81, (byte) 58, (byte) 36, (byte)120, (byte) 50,
-            (byte)165, (byte)203, (byte)149, (byte) 45, (byte) 93, (byte)170,
-            (byte)148, (byte)200, (byte) 81, (byte)102, (byte) 74, (byte)152,
-            (byte)255, (byte)108, (byte)206, (byte)252, (byte) 72, (byte) 17,
-            (byte) 64, (byte) 64, (byte)  0, (byte)  0, (byte) 59
-            };
-
-        return java.awt.Toolkit.getDefaultToolkit().createImage(data);
-        }
-
-}
diff --git a/samples/ui/Makefile b/samples/ui/Makefile
deleted file mode 100644
index b325fe5..0000000
--- a/samples/ui/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# Makefile for directory ./ui
-
-TARGETS=\
-	DefaultImages.class\
-	DOMParserSaveEncoding.class\
-	DOMTree.class\
-	DOMTreeFull.class\
-	TreeView.class\
-	TreeViewer.class
-
-DIRS = 
-
-TOP = ../..
-include $(TOP)/src/Makefile.incl
diff --git a/samples/ui/TreeView.java b/samples/ui/TreeView.java
deleted file mode 100644
index 45d1a63..0000000
--- a/samples/ui/TreeView.java
+++ /dev/null
@@ -1,948 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package ui;                    
-                    
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-import java.io.*;
-import javax.swing.*;
-import javax.swing.tree.*;
-import javax.swing.event.*;
-import java.net.URL;
-import java.net.MalformedURLException;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Element;
-import org.w3c.dom.Text;
-import org.xml.sax.InputSource;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.apache.xerces.parsers.DOMParser;
-import ui.DOMParserSaveEncoding;
-
-
-
-/**
- * A sample DOM Tree Viewer. This sample program illustrates how to
- * traverse a DOM tree and display it in a Swing JTree View.
- *
- * @version
- */
-public class TreeView extends JFrame implements ActionListener, TextListener {
-
-    //
-    // Constants
-    //
-
-    static final boolean DEBUG = true;
-  
-    /** Default parser name. */
-    static final String 
-        DEFAULT_PARSER_NAME = "org.apache.xerces.parsers.DOMParser";
-    static int WARNING = 0;
-    static int ERROR=1;
-    static int FATAL_ERROR=2;
-        
-
-    static final String title = "TreeViewer";
-    static final String openString = "Open";
-    static final String quitString = "Quit";
-    static final String reloadString = "Reload current XML file";
-    static final String expandString = "Expand Tree";
-    static final String collapseString = "Collapse Tree";
-
-    //
-    // Data
-    //
-
-    ErrorStorer ef;
-    String fname;
-    DOMTree m_tree;
-    JTextArea sourceText, messageText;
-    Vector textLine;
-    FileNameInput fni;
-    DOMParserSaveEncoding parser;
-    Image openFolder;
-    Image closedFolder;
-    Image leafImage;
-
-    /**
-     *  Constructor
-     */
-    public TreeView() {
-        this(null);
-    }
-
-    /**
-     *  Constructor
-     */
-    public TreeView(String uri) {
-        super(uri);
-        openFolder = DefaultImages.createOpenFolderImage();
-        closedFolder = DefaultImages.createClosedFolderImage();
-        leafImage = DefaultImages.createLeafImage();
-        parser = new DOMParserSaveEncoding();
-        ef = new ErrorStorer();
-        fname = uri;
-        JMenuBar jmb = new JMenuBar();
-        JMenu fileMenu = new JMenu("File");
-        JMenuItem item;
-
-        item = new JMenuItem(openString);
-        fileMenu.add(item);
-        item.addActionListener(this);
-
-        item = new JMenuItem(quitString);
-        fileMenu.add(item);
-        item.addActionListener(this);
-
-        JMenu shortcutMenu = new JMenu("Shortcuts");
-
-        item = new JMenuItem(expandString);
-        shortcutMenu.add(item);
-        item.addActionListener(this);
-
-        item = new JMenuItem(collapseString);
-        shortcutMenu.add(item);
-        item.addActionListener(this);
-
-        item = new JMenuItem(reloadString);
-        shortcutMenu.add(item);
-        item.addActionListener(this);
-
-        jmb.add(fileMenu);
-        jmb.add(shortcutMenu);
-        setJMenuBar(jmb);
-
-        getContentPane().add(createUI(fname));
-        
-    }
-
-    /** create and return the entire UI from the root TreeNode
-     */
-    JComponent createUI(String filename) {
-        if (DEBUG) System.out.println("START createUI:"+filename);
-
-        // create the message panel first so we can send messages to it...
-        messageText = new JTextArea(3,40);
-        messageText.setFont(new Font("dialog", Font.PLAIN, 12));
-        JPanel messagePanel = new JPanel(new BorderLayout());
-        messagePanel.add(new JScrollPane(messageText) {
-            public Dimension getPreferredSize(){
-                Dimension size = TreeView.this.getSize();
-                return new Dimension(size.width, size.height / 4);
-                }
-            public Dimension getMinimumSize(){
-                return new Dimension(100, 100);
-                }
-            },
-            BorderLayout.CENTER);
-        messagePanel.setBorder(BorderFactory.createCompoundBorder(
-            BorderFactory.createTitledBorder("Messages"),
-            BorderFactory.createEmptyBorder(4, 4, 4, 4)
-            ));
-
-        // create the TextArea for XML source
-        sourceText = new JTextArea();
-        sourceText.setFont(new Font("monospaced", Font.PLAIN, 12));
-        sourceText.setBackground(Color.white);
-        sourceText.setForeground(Color.black);
-        sourceText.setSelectedTextColor(Color.black);
-        sourceText.setSelectionColor(Color.red);
-        sourceText.setEditable(false);
-        JPanel sourcePanel = new JPanel(new BorderLayout());
-        sourcePanel.add(new JScrollPane(sourceText){
-            public Dimension getPreferredSize(){
-                Dimension size = TreeView.this.getSize();
-                return new Dimension(size.width / 2, size.height * 3 / 5);
-                }
-            public Dimension getMinimumSize(){
-                return new Dimension(100, 100);
-                }
-            },
-            BorderLayout.CENTER);
-        sourcePanel.setBorder(BorderFactory.createCompoundBorder(
-            BorderFactory.createTitledBorder("Source View"),
-            BorderFactory.createEmptyBorder(4, 4, 4, 4)
-            ));
-
-        // create the JTree and scroll pane.
-        JPanel treePanel = new JPanel(new BorderLayout());
-        m_tree = new DOMTree();
-        m_tree.setCellRenderer(new XMLTreeCellRenderer());
-        m_tree.getSelectionModel().setSelectionMode
-            (TreeSelectionModel.SINGLE_TREE_SELECTION);
-
-        // Listen for when the selection changes, call nodeSelected(node)
-        m_tree.addTreeSelectionListener(
-            new TreeSelectionListener() {
-                public void valueChanged(TreeSelectionEvent e) {
-                    TreeNode node = (TreeNode)
-                        (e.getPath().getLastPathComponent());
-
-                    nodeSelected(node);
-                }
-            }
-        );
-        m_tree.setRowHeight(18);
-        m_tree.setFont(new Font("dialog", Font.PLAIN, 12));
-
-        treePanel.add(new JScrollPane(m_tree) {
-            public Dimension getPreferredSize(){
-                Dimension size = TreeView.this.getSize();
-                return new Dimension(size.width / 2, size.height * 3 / 5);
-                }
-            public Dimension getMinimumSize(){
-                return new Dimension(100, 100);
-                }
-            },
-            BorderLayout.CENTER);
-
-        treePanel.setBorder(BorderFactory.createCompoundBorder(
-            BorderFactory.createTitledBorder("Tree View"),
-            BorderFactory.createEmptyBorder(4, 4, 4, 4)
-            ));
-
-        // refreshUI loads everthything!
-        refreshUI(filename);
-
-        // use the new JSplitPane to dynamically resize...
-        JComponent split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
-            true, treePanel, sourcePanel);
-
-        JComponent mainSplitPane =
-            new JSplitPane(JSplitPane.VERTICAL_SPLIT,
-                           true, split, messagePanel);
-
-        if (DEBUG) System.out.println("END createUI:"+filename);
-        return mainSplitPane;
-    }
-
-    /** refreshUI is called when we have a new filename to parse.
-     */
-    void refreshUI(String filename) {
-        if (DEBUG) System.out.println("START refreshUI:"+filename);
-
-        messageText.selectAll();
-        messageText.cut();
-
-        if (filename == null || filename.equals("")) {
-            messageText.setForeground(Color.red);
-            messageText.append("No input XML filename specified:"+filename+"\n");
-            return;
-        }
-
-        fname = filename;
-        Document newRoot = getRoot(filename);
-        if (newRoot == null) {
-            messageText.setForeground(Color.red);
-            messageText.append("Unable to get new DOM Tree for:"+filename+"\n");
-            return;
-        }
-        m_tree.setDocument(newRoot);
-
-        // new Source
-        sourceText.selectAll();
-        sourceText.cut();
-        readXMLFile(fname, sourceText);
-
-        setTitle(title+": "+filename);
-
-        if (m_tree!= null)
-            expandTree();
-
-
-        if (ef != null && ef.getErrorNodes()!=null       
-                    && ef.getErrorNodes().size() > 0 ) {
-            messageText.setForeground(Color.red);
-            messageText.append("XML source, "+fname+" has errors.\n");
-            messageText.append("Please click on red Tree View items for details.\n");
-            /***/
-            Hashtable errors = ef.getErrorNodes();
-            Enumeration keys = errors.keys();
-            while (keys.hasMoreElements()) {
-                Node node = (Node)keys.nextElement();
-                messageText.append("node="+node.getNodeName()
-                +", error="+((ParseError)errors.get(node)).getMsg()+"\n");
-            }
-        }
-        if (DEBUG) System.out.println("END refreshUI:"+filename);
-    }
-
-    /**
-     *  Invoke the Parser on fname and return the root TreeNode.
-     */
-    public Document getRoot(String filename) {
-        if (DEBUG) System.out.println("START getRoot:"+filename);
-
-        if (filename == null || filename.equals(""))
-        return null;
-
-        try {
-            //
-            // Reset the Error Storage and handling
-            //
-     
-            ef.resetErrors();
-            parser.setErrorHandler(ef);
-            parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false); // otherwise parser.getCurrentNode() == null
-            parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
-            parser.setFeature("http://apache.org/xml/features/allow-java-encodings", true);
-            parser.parse(filename);
-            Document document = parser.getDocument();
-            /***/
-            return document;
-        } catch (Exception e) {
-             System.err.println( "Error: Invalid XML document could not get ROOT" );
-             System.exit( 1 );
-            //e.printStackTrace(System.err);
-        }
-        return null;
-    }
-
-    /** read the xml file from filename and append it to the JTextArea
-     */
-    synchronized void readXMLFile(String filename, JTextArea ta) {
-
-        if (DEBUG) System.out.println("START readXMLFile"+filename);
-        if (filename == null || filename.equals(""))
-            return;
-        InputStream fis = null;
-        BufferedReader dis = null;
-        try {
-            java.net.URL file = createURL(filename);
-            fis = file.openStream();
-
-            String javaEncoding = parser.getJavaEncoding(); // get saved java encoding
-            try
-            {
-            dis = new BufferedReader(new InputStreamReader(fis, javaEncoding ));
-            }
-            catch( UnsupportedEncodingException ex )
-            {
-            dis = new BufferedReader(new InputStreamReader(fis ));
-            }
-        } catch (Exception ex) {
-            System.err.println("ERROR: Xerces.readXMLFile: "+ex);
-            return;
-        }
-
-        String line;
-        int i = 0;
-
-        int len = 0;
-        textLine = new Vector();
-        String nl = "\n";
-        int nllen = nl.length();
-        StringBuffer sb = new StringBuffer();
-
-        try{
-            readline: while ((line = dis.readLine()) != null) {
-                sb.append(line+nl);
-                textLine.addElement(new Integer(len));
-                len += line.length()+nllen;
-            }
-            ta.append(sb.toString());
-        } catch (IOException io) {
-            System.err.println(io);
-            return;
-        }
-
-        // relayout because contents have changed
-        //ta.revalidate();
-
-        if (DEBUG) System.out.println("END readXMLFile"+filename);
-        return;
-
-    }
-
-    /** called when our JTree's nodes are selected.
-     */
-    void nodeSelected(TreeNode treeNode) {
-
-        Node node = m_tree.getNode(treeNode);
-
-        if( node == null )     // It is possible to get a null node
-            return;
-
-        StringBuffer sb = new StringBuffer();
-        messageText.selectAll();
-        messageText.cut();
-
-
-        //fix
-
-       //JTextArea sourceText = sourceText;
-       Object errorObject = ef == null ? null : ef.getError(node);
-       if (errorObject != null) {
-           // There *is* an error in this node.
-           messageText.setForeground(Color.red);
-           ParseError eip = (ParseError)errorObject;
-           sb.append("Error: "+eip.getMsg()+"\n");
-           int lineNo = eip.getLineNo();
-           int pos  = 0;
-           int next = 0;                       
-           int sizeOfTextLine = textLine.size();
-
-           if( lineNo < sizeOfTextLine )
-              {
-              pos = ((Integer)textLine.elementAt(lineNo-1)).intValue();
-              next = (lineNo == sizeOfTextLine ) ?
-               pos :
-               (((Integer)textLine.elementAt(lineNo)).intValue());
-              }
-           else
-              {
-              pos  = (( Integer) textLine.elementAt( sizeOfTextLine - 1 )).intValue();
-              next = pos + 2;
-              }
-
-           sourceText.select(pos, next );
-           //m_textScrollPane.repaint();
-       } else {
-           messageText.setForeground(Color.black);
-           sourceText.select(0, 0 );
-       }
-        
-        //fix
-
-        
-        if (node.getNodeType() == Node.ELEMENT_NODE
-                    || node.getNodeType() == Node.TEXT_NODE 
-                || node.getNodeType() == Node.CDATA_SECTION_NODE )
-                 {
-                    sb.append(node.toString());
-            }
-       
-        messageText.append(sb.toString());
-    }
-
-    /** called when a the text value has changed in the FileNameInput.
-     *  read in new XML file.
-     */
-    public void textValueChanged(TextEvent e) {
-        try {
-            if (fni != null)
-                fni.setVisible(false);
-            fname = ((JTextField)e.getSource()).getText();
-            if (DEBUG) System.out.println("textValueChanged:"+fname);
-            refreshUI(fname);
-
-        } catch (Exception ex) {
-           System.err.println( "Error: while trying to refresh gui" );
-           System.exit( 1 );
-        //    ex.printStackTrace();
-        }
-    }
-
-    /** called to handle menu actions.
-     */
-    public void actionPerformed(java.awt.event.ActionEvent e) {
-        if (DEBUG) System.err.println("ACTION: "+e.getActionCommand()+", "+e.paramString());
-
-        if (e.getActionCommand().equals(quitString)) {
-          System.exit(0);
-        }
-        else if (e.getActionCommand().equals(openString)) {
-
-            fni = new FileNameInput("Open File");
-            fni.addTextListener(this);
-            fni.setVisible(true);
-        }
-        else if (e.getActionCommand().equals(expandString)) {
-            expandTree();
-        }
-        else if (e.getActionCommand().equals(collapseString)) {
-            int rows = m_tree.getRowCount();
-            for (int i = 0; i < rows; i++) {
-                m_tree.collapseRow(i);
-            }
-        }
-        else
-        //if (e.getActionCommand().equals(reloadString)) {
-            refreshUI(fname);
-        //}
-    }
-
-    void expandTree() {
-        int rows = 0;
-        for (int levels=0; levels <= 4; levels++) {
-            rows=m_tree.getRowCount();
-            for (int i = 0; i < rows; i++) {
-                m_tree.expandRow(i);
-            }
-        }
-    }
-
-    /*
-     * The XMLTreeCellRenderer is an inner class which enables the
-     * highlighting of errors in the tree and shows the gender values
-     * as different icons.
-     */
-    class XMLTreeCellRenderer extends DefaultTreeCellRenderer
-    {
-
-        public Component getTreeCellRendererComponent(JTree tree, Object value,
-                          boolean selected, boolean expanded,
-                          boolean leaf, int row,
-                              boolean hasFocus)
-        {
-            Node node = ((DOMTree)tree).getNode(value);
-            Component comp = super.getTreeCellRendererComponent(tree, value,
-                           selected,  expanded, leaf,  row, hasFocus);
-            if (selected) {
-                comp.setBackground(Color.blue);
-            }
-            if (ef != null
-            && ef.getErrorNodes() != null
-            && value != null
-            && node != null
-            && ef.getErrorNodes().containsKey( node )) {
-                comp.setForeground(Color.red);
-            }
-
-            if (node != null) {
-                if (leaf) {
-                    setIcon(new ImageIcon(leafImage));
-                } else if (expanded) {
-                    setIcon(new ImageIcon(openFolder));
-                } else {
-                    setIcon(new ImageIcon(closedFolder));
-                }
-            }
-            if (node != null && node instanceof Element) {
-                
-                Element txNode = (Element)node;
-                Attr txAtt = (Attr)txNode.getAttributeNode("gender");
-                if (txAtt != null) {
-                    if (txAtt.getValue().equals("male")) {
-                        setIcon(new ImageIcon("male.gif"));
-                    } else
-                    if (txAtt.getValue().equals("female")) {
-                        setIcon(new ImageIcon("female.gif"));
-                    }
-                }
-            }
-
-            return comp;
-        }
-    }
-
-    /*
-     * The FileNameInput is an inner class which allows the user
-     * to enter a filename. It exists due to a Swing bug which
-     * has problems with the real file input panel.
-     */
-    class FileNameInput extends JFrame implements ActionListener {
-
-
-        JLabel fileLabel;
-        JTextField textField;
-        JButton ok;
-        JButton cancel;
-        Vector textListeners;
-
-        public FileNameInput() {
-            this("");
-        }
-
-        public FileNameInput(String title) {
-
-            super(title);
-
-            fileLabel = new JLabel("Enter XML file name:");
-            textField = new JTextField();
-            textField.addActionListener(this);
-            ok = new JButton("ok");
-            cancel = new JButton("cancel");
-            JPanel buttonPanel = new JPanel();
-            buttonPanel.add(ok);
-            buttonPanel.add(cancel);
-            ok.addActionListener(this);
-            cancel.addActionListener(this);
-            getContentPane().add(fileLabel, BorderLayout.NORTH);
-            getContentPane().add(textField, BorderLayout.CENTER);
-            getContentPane().add(buttonPanel, BorderLayout.SOUTH);
-            setSize(400,100);
-        }
-
-        public void actionPerformed(ActionEvent e) {
-
-            if (e.getSource() == ok || e.getSource() == textField) {
-                System.out.println("FileNameInput: pressed OK");
-                    TextEvent event = new TextEvent(textField, TextEvent.TEXT_VALUE_CHANGED);
-                    deliverEvent(event);
-                    setVisible(false);
-            } else
-            if (e.getSource() == cancel) {
-                System.out.println("FileNameInput: pressed cancel");
-                    setVisible(false);
-            }
-        }
-
-        /**
-         * Adds a TextListener event listener.
-         *
-         * @param listener  The listener to add.
-         *
-         * @see #removeTextListener
-         */
-        public void addTextListener(TextListener listener) {
-
-            // is there anything to do?
-            if (listener == null)
-                return;
-
-            if (textListeners == null)
-               textListeners = new Vector();
-
-            // add listener
-            textListeners.addElement(listener);
-            }
-
-        /**
-         * Removes a TextListener event listener.
-         *
-         * @param listener  The listener to remove.
-         *
-         * @see #addTextListener
-         */
-        public void removeTextListener(TextListener listener) {
-
-            // is there anything to do?
-            if (listener == null || textListeners == null)
-                return;
-
-            // add listener
-            textListeners.removeElement(listener);
-            }
-
-
-        /**
-         * This function delivers TextListener events, when the ok
-         * button is clicked.
-         *
-         * @param evt The event to deliver.
-         */
-        protected void deliverEvent(EventObject evt) {
-
-            if (evt instanceof TextEvent) {
-                TextEvent event = (TextEvent)evt;
-
-                Vector l;
-                synchronized (textListeners) { l = (Vector)textListeners.clone(); }
-
-                int size = l.size();
-                for (int i = 0; i < size; i++)
-                    ((TextListener)l.elementAt(i)).textValueChanged(event);
-                }
-            }
-    }
-
-    //
-    // Create a URL object from either a URL string or a plain file name.
-    //
-    static URL createURL(String name) throws Exception {
-        try {
-                URL u = new URL(name);
-                return u;
-        } catch (MalformedURLException ex) {
-        }
-        URL u = new URL("file:" + new File(name).getAbsolutePath());
-        return u;
-    }    
-    
-    /**
-     * The ErrorStorer maps Nodes to errors. It receives a reference
-     * to the ErrorTreeFactory in the Constructor.
-     *
-     * When error is called, it asks the
-     * ErrorTreeFactory for the current node, and uses this as the
-     * "key" of a Hashtable, with the error as a value. The error
-     * value is wrapped up nicely in an ParseError object.
-     *
-     * It is used in the XML Tutorial to illustrate how to implement
-     * the ErrorListener to provide error storage for later reference.
-     *
-     */
-    class ErrorStorer 
-        implements ErrorHandler
-        
-    {
-
-        //
-        // Data
-        //
-        Hashtable errorNodes = null;
-        
-        /**
-         * Constructor
-         */
-        public ErrorStorer() {
-        }
-
-        /**
-         * The client is is allowed to get a reference to the Hashtable,
-         * and so could corrupt it, or add to it...
-         */
-        public Hashtable getErrorNodes() {
-            return errorNodes;
-        }
-
-        /**
-         * The ParseError object for the node key is returned.
-         * If the node doesn't have errors, null is returned.
-         */
-        public Object getError(Node node) {
-            if (errorNodes == null)
-                return null;
-            return errorNodes.get(node);
-        }
-        
-        /**
-         * Reset the error storage.
-         */
-        public void resetErrors() {
-            if (errorNodes != null)
-            errorNodes.clear();
-        }
-        
-        /***/
-        public void warning(SAXParseException ex) {
-            handleError(ex, WARNING);
-        }
-
-        public void error(SAXParseException ex) {
-            handleError(ex, ERROR);
-        }
-
-        public void fatalError(SAXParseException ex) throws SAXException {
-            handleError(ex, FATAL_ERROR);
-        }
-        
-        private void handleError(SAXParseException ex, int type) {
-            System.out.println("!!! handleError: "+ex.getMessage());
-
-            StringBuffer errorString = new StringBuffer();
-            errorString.append("at line number, ");
-            errorString.append(ex.getLineNumber());
-            errorString.append(": ");
-            errorString.append(ex.getMessage());
-
-            // Node current = parser.getCurrentNode();
-
-            Node current = null ;
-
-            try
-              {
-              current = ( Node ) parser.getProperty( "http://apache.org/xml/properties/dom/current-element-node" );
-              
-              }
-            catch( SAXException exception  )
-              {
-               ;
-              }
-
-            if (current == null) {
-                System.err.println("Error in handleError. getCurrentNode()==null!");
-                return;
-            }
-            
-            if (errorNodes == null)
-                errorNodes = new Hashtable();
-            ParseError previous = (ParseError) errorNodes.get(current);
-            ParseError eip  = null;
-            // if a Node already has an error, we accumulate the text here...
-            if (previous != null) {
-                eip = previous;
-                errorString = new StringBuffer(previous.getMsg()+"\n"+errorString.toString());
-                eip.setMsg(errorString.toString());
-            } else {
-                eip = new
-                    ParseError(
-                        ex.getSystemId(), 
-                        ex.getLineNumber(), 
-                        ex.getColumnNumber(),
-                        "",  
-                        errorString.toString());
-            }
-
-            // put it in the Hashtable.
-            errorNodes.put(current, eip);
-        }
-        
-    }
-    
-    /**
-     * The ParseError class wraps up all the error info from
-     * the ErrorStorer's error method.
-     *
-     * @see ErrorStorer
-     */
-    class ParseError extends Object {
-
-        //
-        // Data
-        //
-
-        String fileName;
-        int lineNo;
-        int charOffset;
-        Object key;
-        String msg;
-
-        /**
-         * Constructor
-         */
-        public ParseError(String fileName, int lineNo, int charOffset,
-                           Object key, 
-                           String msg)
-        {
-            this. fileName=fileName;
-            this. lineNo=lineNo;
-            this. charOffset=charOffset;
-            this. key=key;
-            this. msg=msg;
-        }
-
-        //
-        // Getters...
-        //
-        public String getFileName() { return fileName; }
-        public int getLineNo() { return lineNo; }
-        public int getCharOffset() { return charOffset;}
-        public Object getKey() { return key; }
-        public String getMsg() { return msg; }
-        public void setMsg(String s) { msg = s; }
-    }
-
-
-    //
-    // Main
-    //
-    
-    /** Main program entry point. */
-    public static void main(String argv[]) {
-        
-        // vars
-        int parserNameIndex = -1;
-        String parserName = DEFAULT_PARSER_NAME;
-
-        // check parameters
-        for (int i = 0; i < argv.length; i++) {
-            String arg = argv[i];
-
-            // options
-            if (arg.startsWith("-")) {
-                if (arg.equals("-p")) {
-                    if (i == argv.length - 1) {
-                        System.err.println("error: missing parser class");
-                        System.exit(1);
-                    }
-                    parserName = argv[++i];
-                    parserNameIndex = i;
-                    continue;
-                }
-
-                if (arg.equals("-h")) {
-                    printUsage();
-                    System.exit(1);
-                }
-            }
-
-            // print uri
-            System.err.println(arg+':');
-   
-            JFrame frame = null;
-            if (parserNameIndex == argv.length-1) {
-                // null behaviour is blank screen - eg no JTree, or file dispalyed
-                frame = new TreeView("");
-            } else {
-                frame = new TreeView(arg);
-            }
-            frame.addWindowListener(new java.awt.event.WindowAdapter() {
-             public void windowClosing(java.awt.event.WindowEvent e) {
-                 System.exit(0);
-             }
-            });
-            frame.setSize(790, 590);
-            frame.setVisible(true);
-        }
-    } // main(String[])
-
-    /** Prints the usage. */
-    private static void printUsage() {
-
-        System.err.println("usage: java ui.TreeViewer (options) uri ...");
-        System.err.println();
-        System.err.println("options:");
-        System.err.println("  -p name  Specify DOM parser class by name.");
-        System.err.println("           Default parser: "+DEFAULT_PARSER_NAME);
-        System.err.println("  -h       This help screen.");
-
-    } // printUsage()
-
-} // class TreeViewer
diff --git a/samples/ui/TreeViewer.java b/samples/ui/TreeViewer.java
deleted file mode 100644
index fcd2808..0000000
--- a/samples/ui/TreeViewer.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package ui;
-
-/*
- *
- * command line invocation wrapper for TreeViewer
- *
- * @version
- */
-
-public class TreeViewer {
-
-    public TreeViewer() {
-        System.out.println("TreeViewer is no longer an instantiable class.  Please use XMLTreeView instead.");
-        throw new RuntimeException();
-    }
-
-    public TreeViewer(String title, String filename) {
-        System.out.println("TreeViewer is no longer an instantiable class.  Please use XMLTreeView instead.");
-        throw new RuntimeException();
-    }
-
-    public static void main(String[] argv) {
-        try {
-            Class.forName("javax.swing.JFrame");
-        } catch (ClassNotFoundException cnfe) {
-            System.out.println("Couldn't load class javax.swing.JFrame.");
-            System.out.println("This sample now uses Swing version 1.1.  Couldn't find the Swing 1.1 classes, please check your CLASSPATH settings.");
-            System.exit(1);
-        }
-
-        TreeView.main(argv);
-    }
-
-}
-
diff --git a/samples/util/Arguments.java b/samples/util/Arguments.java
deleted file mode 100644
index 78c52aa..0000000
--- a/samples/util/Arguments.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000  The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-
-package util;
-import java.lang.Integer;
-
-
-
-/**
- * Utility like Unix getopt.
- * 
- * Usage:
- * 
- * int c;
- * 
- *         parseArgumentTokens(argv);
- *         while ( (c =  getArguments()) != -1 ){
- * 
- *          switch (c) {
- *             case 'v':
- *                 System.out.println( "v" );
- *                 break;
- *             case 'V':
- *                 System.out.println( "V" );
- *                 break;
- * 
- * @version $id$
- * @author Jeffrey Rodriguez
- */
-
-public class Arguments {
-    private  boolean      fDbug                        = false;
-    private  Queue        queueOfSwitches              = new Queue(20);
-    private  Queue        queueStringParameters        = new Queue(20);
-    private  Queue        queueOfOtherStringParameters = new Queue(20);
-    private  String[]     messageArray                 = null; 
-    private  int          lastPopArgument              = 0;
-
-
-    public Arguments() {
-    }
-
-    /**
-     * Takes the array of standar Args passed
-     * from main method and parses the '-' and
-     * the characters after arg.
-     * 
-     * - The value -1 is a special flag that is
-     * used to indicate the beginning of the queue
-     * of flags and it is also to tell the end of
-     * a group of switches.
-     * 
-     * This method will generate 3 internal queues.
-     * - A queue that has the switch flag arguments.
-     *   e.g. 
-     *          -dvV
-     *   will hold  d, v, V, -1.
-     * 
-     * - A queue holding the string arguments needed by
-     *   the switch flag arguments.
-     *   If character -p requires a string argument.
-     *   The string argument is saved in the string argument
-     *   queue.
-     * 
-     * - A queue holding a list of files string parameters
-     *   not associated with a switch flag.
-     *   -a -v -p myvalue  test.xml test1.xml
-     *   this queue will containt test.xml test1.xml
-     * 
-     * @param arguments
-     * @param argsWithOptions
-     */
-    public void    parseArgumentTokens(  String[] arguments , char[] argsWithOptions ){
-        int  theDash         = 0;
-        int  lengthOfToken   = 0;
-        char []bufferOfToken = null;
-        Object[] temp;
-
-        int  argLength = arguments.length;
-
-        outer:
-        for ( int i = 0; i<argLength; i++ ){
-            bufferOfToken = arguments[i].toCharArray();
-            lengthOfToken = bufferOfToken.length;
-            if ( bufferOfToken[0] == '-' ){
-                int   token;
-                //System.out.println( "argv = " + arguments[i] );
-                //System.out.println( "leng = " + lengthOfToken );
-                for ( int j = 1; j<lengthOfToken; j++ ){
-                    token = bufferOfToken[j];
-                    //System.out.println( "token = " + token );
-                    queueOfSwitches.push( (Object ) new Integer( token ));
-                    for ( int k = 0; k< argsWithOptions.length; k++) {
-                        if ( token == argsWithOptions[k] ){
-                            if ( this.fDbug  ) {
-                                System.out.println( "token = " + token );
-                            }
-                            //queueOfSwitches.push( (Object ) new Integer( -1 ));
-                            queueStringParameters.push( arguments[++i] );
-                            continue outer;
-                        }
-                    }
-
-                }
-
-                if ( i+1 < argLength ){
-                    if ( !( arguments[i+1].charAt(0) == '-') ) //next argument not start '-'
-                        queueOfSwitches.push( (Object ) new Integer( -1 )); //put -1 marker 
-                }
-
-            } else{
-                queueOfOtherStringParameters.push( arguments[i] );
-            }
-        }
-
-
-        if ( this.fDbug ) {
-            queueOfSwitches.print();
-            queueStringParameters.print();
-            queueOfOtherStringParameters.print();
-        }
-    }
-
-
-    /**
-     * 
-     * @return 
-     */
-    public  int getArguments(){
-        if ( this.fDbug ){
-            queueOfSwitches.print();
-        }
-
-        //int value = ((Integer ) queueOfSwitches.pop()).intValue();
-        //if ( this.fDbug ) {
-          //  System.out.println("value = " + value );
-        //}
-        return queueOfSwitches.empty() ? -1:((Integer ) queueOfSwitches.pop()).intValue();
-    }
-
-
-
-    /**
-     * 
-     * @return 
-     */
-    public String getStringParameter(){
-        String    s = (String) queueStringParameters.pop();
-        if ( this.fDbug ){
-            queueStringParameters.print();
-        }
-        if ( this.fDbug )  {
-            System.out.println( "string par = " + s );
-        }
-        return s;
-    }
-
-
-    public String getlistFiles(){
-
-        if ( this.fDbug ) {
-            queueOfOtherStringParameters.print();
-        }
-
-        String s = (String) queueOfOtherStringParameters.pop(); 
-        return s;
-    }
-
-
-
-    public int stringParameterLeft( ){
-        return queueStringParameters.size();
-    }
-
-
-    public void setUsage( String[] message ){ 
-        messageArray = message;
-    }
-
-    public void printUsage() {
-        for ( int i = 0; i< messageArray.length; i++ ){
-            System.err.println( messageArray[i] );
-        }
-    }
-
-    // Private methods
-
-    // Private inner classes
-
-
-    private static final int  maxIncrement = 10;
-
-    private  class Queue   {
-        //private LinkedList queue;
-        private Object[]          queue;
-        private int               max;
-        private int               front; 
-        private int               rear;
-        private int               items;
-
-
-        public Queue( int size) {
-            queue  = new Object[size];
-            front  = 0;
-            rear   = -1;
-            items  = 0;
-            max    = size;
-            //queue = new LinkedList();
-        }
-        public void push( Object token ) {
-            try {
-                queue[++rear] = token;
-                items++;
-            } catch ( ArrayIndexOutOfBoundsException ex ){
-                Object[] holdQueue = new Object[max + maxIncrement]; 
-                System.arraycopy(queue, 0, holdQueue,0,max );
-                queue = holdQueue;
-                max   += maxIncrement;
-                queue[rear] = token;
-                items++;
-            }
-
-            //queue.addLast( token );
-        }
-        public Object pop() {
-            Object token = null;
-            if ( items != 0 ) {
-                token = queue[front++];
-                items--;
-            }
-            return token; 
-        }
-        public boolean empty(){
-            return(items==0);
-        }
-
-        public int size(){
-            return items;
-        }
-
-        public void clear(){
-            front  = 0;
-            rear   = -1;
-            items  = 0;
-        }
-
-
-        public void print(){
-            for ( int i = front; i <= rear;i++ ){ 
-                System.out.println( "token[ " +  i
-                                    + "] = " +  queue[i] ) ;
-            }
-
-        }
-
-    }
-}
diff --git a/samples/util/Makefile b/samples/util/Makefile
deleted file mode 100644
index 444967a..0000000
--- a/samples/util/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# Makefile for directory ./util
-
-TARGETS=\
-	Arguments.class
-
-DIRS = 
-
-TOP = ../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/Makefile b/src/Makefile
deleted file mode 100644
index 86c4298..0000000
--- a/src/Makefile
+++ /dev/null
@@ -1,549 +0,0 @@
-# Makefile for directory .
-
-TARGETS =
-DIRS = org javax
-
-TOP = ..
-include $(TOP)/src/Makefile.incl
-
-apidocs: ../docs/apiDocs/index.html
-../docs/apiDocs/index.html: classfiles_updated
-
-	$(JAVADOC12) -classpath "$(CLPATH)" \
-		-windowtitle "Xerces ${PRODUCTVERSION_DOT} API" \
-		-splitindex -header "Xerces ${PRODUCTVERSION_DOT}" \
-		-version  \
-		-d ../docs/apiDocs ${PACKAGES}
-
-jars: source samples
-
-source: ../bin/${JARFILE}
-../bin/${JARFILE}: classfiles_updated
-
-#########################################
-#copy the .class and .dtd files under src
-#-src/org/apache/xerces/dom
-	${MKDIR} ../class/org/apache/xerces/dom
-	${CP}  ../src/org/apache/xerces/dom/*.class  			../class/org/apache/xerces/dom
-
-#-src/org/apache/xerces/dom/events
-	${MKDIR} ../class/org/apache/xerces/dom/events       
-	${CP}  ../src/org/apache/xerces/dom/events/*.class  		../class/org/apache/xerces/dom/events
-
-#-src/org/apache/xerces/domx
-	${MKDIR} ../class/org/apache/xerces/domx
-	${CP}  ../src/org/apache/xerces/domx/*.class  		../class/org/apache/xerces/domx
-
-#-src/org/apache/xerces/framework
-	${MKDIR} ../class/org/apache/xerces/framework
-	${CP}  ../src/org/apache/xerces/framework/*.class		../class/org/apache/xerces/framework
-
-#-src/org/apache/xerces/infoset
-#	${MKDIR} ../class/org/apache/xerces/infoset
-#	${CP}  ../src/org/apache/xerces/infoset/*.class			../class/org/apache/xerces/infoset
-
-#-src/org/apache/xerces/internal/msg
-#	${MKDIR} ../class/org/apache/xerces/internal/msg
-#	${CP}  ../src/org/apache/xerces/internal/msg/*.class		../class/org/apache/xerces/internal/msg
-
-#-src/org/apache/xerces/msg
-	${MKDIR} ../class/org/apache/xerces/msg
-	${CP}  ../src/org/apache/xerces/msg/*.class                      ../class/org/apache/xerces/msg
-
-#-src/org/apache/xerces/parsers
-	${MKDIR} ../class/org/apache/xerces/parsers
-	${CP}  ../src/org/apache/xerces/parsers/*.class			../class/org/apache/xerces/parsers
-
-#-src/org/apache/xerces/readers
-	${MKDIR} ../class/org/apache/xerces/readers
-	${CP}  ../src/org/apache/xerces/readers/*.class                  ../class/org/apache/xerces/readers
-	${CP}  ../src/org/apache/xerces/readers/*.dtd                    ../class/org/apache/xerces/readers
-
-#-src/org/apache/xerces/utils
-	${MKDIR} ../class/org/apache/xerces/utils
-	${CP}  ../src/org/apache/xerces/utils/*.class                    ../class/org/apache/xerces/utils
-
-#-src/org/apache/xerces/utils/regex
-	${MKDIR} ../class/org/apache/xerces/utils/regex
-	${CP}  ../src/org/apache/xerces/utils/regex/*.class                    ../class/org/apache/xerces/utils/regex
-
-#-src/org/apache/xerces/validators/common
-	${MKDIR} ../class/org/apache/xerces/validators/common
-	${CP}  ../src/org/apache/xerces/validators/common/*.class      ../class/org/apache/xerces/validators/common
-
-#-src/org/apache/xerces/validators/datatype
-	${MKDIR} ../class/org/apache/xerces/validators/datatype
-	${CP}  ../src/org/apache/xerces/validators/datatype/*.class      ../class/org/apache/xerces/validators/datatype
-
-#-src/org/apache/xerces/validators/dtd
-	${MKDIR} ../class/org/apache/xerces/validators/dtd
-	${CP}  ../src/org/apache/xerces/validators/dtd/*.class           ../class/org/apache/xerces/validators/dtd
-
-#-src/org/apache/xerces/validators/schema
-	${MKDIR} ../class/org/apache/xerces/validators/schema
-	${CP}  ../src/org/apache/xerces/validators/schema/*.class        ../class/org/apache/xerces/validators/schema
-	${CP}  ../src/org/apache/xerces/validators/schema/*.dtd          ../class/org/apache/xerces/validators/schema
-	${CP}  ../src/org/apache/xerces/validators/schema/*.ent          ../class/org/apache/xerces/validators/schema
-
-#-src/org/apache/xml/serialize
-	${MKDIR} ../class/org/apache/xml/serialize
-	${CP}  ../src/org/apache/xml/serialize/*.class                  ../class/org/apache/xml/serialize
-	${CP}  ../src/org/apache/xml/serialize/*.res                    ../class/org/apache/xml/serialize 
-
-#-src/org/apache/html/dom
-	${MKDIR} ../class/org/apache/html
-	${MKDIR} ../class/org/apache/html/dom
-	${CP}  ../src/org/apache/html/dom/*.class                  ../class/org/apache/html/dom
-
-#-src/org/w3c/dom
-	${MKDIR} ../class/org/w3c/dom	
-	${CP}  ../src/org/w3c/dom/*.class				../class/org/w3c/dom
-
-#-src/org/w3c/dom/events
-	${MKDIR} ../class/org/w3c/dom/events	
-	${CP}  ../src/org/w3c/dom/events/*.class			../class/org/w3c/dom/events
-
-#-src/org/w3c/dom/range
-	${MKDIR} ../class/org/w3c/dom/range	
-	${CP}  ../src/org/w3c/dom/range/*.class			../class/org/w3c/dom/range
-
-#-src/org/w3c/dom/html
-	${MKDIR} ../class/org/w3c/dom/html	
-	${CP}  ../src/org/w3c/dom/html/*.class				../class/org/w3c/dom/html
-
-#-src/org/w3c/dom/traversal
-	${MKDIR} ../class/org/w3c/dom/traversal	
-	${CP}  ../src/org/w3c/dom/traversal/*.class			../class/org/w3c/dom/traversal
-
-#-src/org/xml/sax
-	${MKDIR} ../class/org/xml/sax
-	${CP}  ../src/org/xml/sax/*.class				../class/org/xml/sax
-
-#-src/org/xml/sax/helpers
-	${MKDIR} ../class/org/xml/sax/helpers
-	${CP}  ../src/org/xml/sax/helpers/*.class			../class/org/xml/sax/helpers
-
-#-src/org/xml/sax/ext
-	${MKDIR} ../class/org/xml/sax/ext
-	${CP}  ../src/org/xml/sax/ext/*.class			../class/org/xml/sax/ext
-
-#-src/org/apache/wml
-	${MKDIR} ../class/org/apache/wml
-	${CP}  ../src/org/apache/wml/*.class                  ../class/org/apache/wml
-	${MKDIR} ../class/org/apache/wml/dom
-	${CP}  ../src/org/apache/wml/dom/*.class                  ../class/org/apache/wml/dom
-
-#-src/javax/xml/parsers
-	${MKDIR} ../class/javax/xml/parsers
-	${CP}  ../src/javax/xml/parsers/*.class                  ../class/javax/xml/parsers
-
-#-src/org/apache/xerces/jaxp
-	${MKDIR} ../class/org/apache/xerces/jaxp
-	${CP}  ../src/org/apache/xerces/jaxp/*.class                  ../class/org/apache/xerces/jaxp
-
-
-#make the first jar file
-	echo ${PRODUCTVERSION}> ../class/Xerces_Ver_${PRODUCTVERSION}.info
-	cd ../class;$(JAR) c0vf ../bin/${JARFILE} *.info org javax; cd ../src
-
-###################################
-#copy the .class files under samples
-samples: ../bin/${SAMPLESJARFILE}
-../bin/${SAMPLESJARFILE}: classfiles_updated
-
-#-samples/dom
-
-	${MKDIR} ../class/dom
-	${CP}  ../samples/dom/*.class  ../class/dom
-
-#-samples/dom/traversal
-
-	${MKDIR} ../class/dom/traversal
-	${CP}  ../samples/dom/traversal/*.class                    ../class/dom/traversal
-
-#-samples/dom/wrappers
-
-	${MKDIR} ../class/dom/wrappers
-	${CP}  ../samples/dom/wrappers/*.class                     ../class/dom/wrappers
-
-#-samples/sax
-
-	${MKDIR} ../class/sax
-	${CP}  ../samples/sax/*.class  ../class/sax
-
-#-samples/sax/helpers
-
-	${MKDIR}  ../class/sax/helpers
-	${CP}  ../samples/sax/helpers/*.class                      ../class/sax/helpers
-
-#-samples/ui
-
-	${MKDIR}  ../class/ui
-	${CP}  ../samples/ui/*.class  ../class/ui
-
-
-#-samples/util
-
-	${MKDIR}  ../class/util
-	${CP}  ../samples/util/*.class  ../class/util
-
-
-
-#Make the second jar file
-
-	cd ../class;$(JAR) c0vf ../bin/${SAMPLESJARFILE} Xerces_Ver_${PRODUCTVERSION}.info dom sax ui util;cd ../src
-
-# copy the license, ANT build file, Status file, and READMEs
-	${CP}  ../Readme.html ../bin
-
-
-package_src:
-
-##################################################
-#copy the .java .dtd files under src
-
-#-src/org/apache/wml
-	${MKDIR} ../source/src/org/apache/wml
-	${CP}  ../src/org/apache/wml/*.java  			../source/src/org/apache/wml
-
-#-src/org/apache/wml/dom
-	${MKDIR} ../source/src/org/apache/wml/dom
-	${CP}  ../src/org/apache/wml/dom/*.java  			../source/src/org/apache/wml/dom
-
-#-src/org/apache/html/dom
-	${MKDIR} ../source/src/org/apache/html/dom
-	${CP}  ../src/org/apache/html/dom/*.java  			../source/src/org/apache/html/dom
-
-#-src/org/apache/xerces/dom
-	${MKDIR} ../source/src/org/apache/xerces/dom
-	${CP}  ../src/org/apache/xerces/dom/*.java  			../source/src/org/apache/xerces/dom
-
-#-src/org/apache/xerces/dom/events
-	${MKDIR} ../source/src/org/apache/xerces/dom/events       
-	${CP}  ../src/org/apache/xerces/dom/events/*.java  		../source/src/org/apache/xerces/dom/events
-
-#-src/org/apache/xerces/domx
-	${MKDIR} ../source/src/org/apache/xerces/domx
-	${CP}  ../src/org/apache/xerces/domx/*.java  		../source/src/org/apache/xerces/domx
-
-#-src/org/apache/xerces/framework
-	${MKDIR} ../source/src/org/apache/xerces/framework
-	${CP}  ../src/org/apache/xerces/framework/*.java		../source/src/org/apache/xerces/framework
-
-#-src/org/apache/xerces/infoset
-#	${MKDIR} ../source/src/org/apache/xerces/infoset
-#	${CP}  ../src/org/apache/xerces/infoset/*.java			../source/src/org/apache/xerces/infoset
-
-#-src/org/apache/xerces/internal/msg
-#	${MKDIR} ../source/src/org/apache/xerces/internal/msg
-#	${CP}  ../src/org/apache/xerces/internal/msg/*.java		../source/src/org/apache/xerces/internal/msg
-
-#-src/org/apache/xerces/msg
-	${MKDIR} ../source/src/org/apache/xerces/msg
-	${CP}  ../src/org/apache/xerces/msg/*.java                      ../source/src/org/apache/xerces/msg
-
-#-src/org/apache/xerces/parsers
-	${MKDIR} ../source/src/org/apache/xerces/parsers
-	${CP}  ../src/org/apache/xerces/parsers/*.java			../source/src/org/apache/xerces/parsers
-
-#-src/org/apache/xerces/readers
-	${MKDIR} ../source/src/org/apache/xerces/readers
-	${CP}  ../src/org/apache/xerces/readers/*.java                  ../source/src/org/apache/xerces/readers
-
-#-src/org/apache/xerces/readers
-	${MKDIR} ../source/src/org/apache/xerces/readers
-	${CP}  ../src/org/apache/xerces/readers/*.dtd                    ../source/src/org/apache/xerces/readers
-
-#-src/org/apache/xerces/utils
-	${MKDIR} ../source/src/org/apache/xerces/utils
-	${CP}  ../src/org/apache/xerces/utils/*.java                    ../source/src/org/apache/xerces/utils
-
-#-src/org/apache/xerces/utils/regex
-	${MKDIR} ../source/src//org/apache/xerces/utils/regex
-	${CP}  ../src/org/apache/xerces/utils/regex/*.java                    ../source/src/org/apache/xerces/utils/regex
-
-
-#-src/org/apache/xerces/validaters/common
-	${MKDIR} ../source/src/org/apache/xerces/validators/common
-	${CP}  ../src/org/apache/xerces/validators/common/*.java      ../source/src/org/apache/xerces/validators/common
-
-#-src/org/apache/xerces/validaters/datatype
-	${MKDIR} ../source/src/org/apache/xerces/validators/datatype
-	${CP}  ../src/org/apache/xerces/validators/datatype/*.java      ../source/src/org/apache/xerces/validators/datatype
-
-#-src/org/apache/xerces/validaters/dtd
-	${MKDIR} ../source/src/org/apache/xerces/validators/dtd
-	${CP}  ../src/org/apache/xerces/validators/dtd/*.java           ../source/src/org/apache/xerces/validators/dtd
-
-#-src/org/apache/xerces/validaters/schema
-	${MKDIR} ../source/src/org/apache/xerces/validators/schema
-	${CP}  ../src/org/apache/xerces/validators/schema/*.java        ../source/src/org/apache/xerces/validators/schema
-	${CP}  ../src/org/apache/xerces/validators/schema/*.dtd          ../source/src/org/apache/xerces/validators/schema
-	${CP}  ../src/org/apache/xerces/validators/schema/*.ent          ../source/src/org/apache/xerces/validators/schema
-
-#-src/org/apache/xml/serialize
-	${MKDIR} ../source/src/org/apache/xml/serialize
-	${CP}  ../src/org/apache/xml/serialize/*.java                   ../source/src/org/apache/xml/serialize
-	${CP}  ../src/org/apache/xml/serialize/*.res                    ../source/src/org/apache/xml/serialize
-
-#-src/org/w3c/dom
-	${MKDIR} ../source/src/org/w3c/dom	
-	${CP}  ../src/org/w3c/dom/*.java				../source/src/org/w3c/dom
-
-#-src/org/w3c/dom/events
-	${MKDIR} ../source/src/org/w3c/dom/events	
-	${CP}  ../src/org/w3c/dom/events/*.java				../source/src/org/w3c/dom/events
-
-#-src/org/w3c/dom/range
-	${MKDIR} ../source/src/org/w3c/dom/range	
-	${CP}  ../src/org/w3c/dom/range/*.java				../source/src/org/w3c/dom/range
-
-#-src/org/w3c/dom/html
-	${MKDIR} ../source/src/org/w3c/dom/html	
-	${CP}  ../src/org/w3c/dom/html/*.java				../source/src/org/w3c/dom/html
-
-#-src/org/w3c/dom/traversal
-	${MKDIR} ../source/src/org/w3c/dom/traversal	
-	${CP}  ../src/org/w3c/dom/traversal/*.java			../source/src/org/w3c/dom/traversal
-
-#-src/org/xml/sax
-	${MKDIR} ../source/src/org/xml/sax
-	${CP}  ../src/org/xml/sax/*.java				../source/src/org/xml/sax
-
-#-src/org/xml/sax/helpers
-	${MKDIR} ../source/src/org/xml/sax/helpers
-	${CP}  ../src/org/xml/sax/helpers/*.java			../source/src/org/xml/sax/helpers
-
-#-src/org/xml/sax/ext
-	${MKDIR} ../source/src/org/xml/sax/ext
-	${CP}  ../src/org/xml/sax/ext/*.java			../source/src/org/xml/sax/ext
-
-#-src/javax/xml/parsers
-	${MKDIR} ../source/src/javax/xml/parsers
-	${CP}  ../src/javax/xml/parsers/*.java                  ../source/src/javax/xml/parsers
-
-#-src/org/apache/xerces/jaxp
-	${MKDIR} ../source/src/org/apache/xerces/jaxp
-	${CP}  ../src/org/apache/xerces/jaxp/*.java                  ../source/src/org/apache/xerces/jaxp
-
-###################################
-#copy the .java and .dtd files unser samples
-
-#-samples/dom
-
-	${MKDIR} ../source/samples/dom
-	${CP}  ../samples/dom/*.java  ../source/samples/dom
-
-#-samples/dom/traversal
-
-	${MKDIR} ../source/samples/dom/traversal
-	${CP}  ../samples/dom/traversal/*.java                    ../source/samples/dom/traversal
-
-#-samples/dom/wrappers
-
-	${MKDIR} ../source/samples/dom/wrappers
-	${CP}  ../samples/dom/wrappers/*.java                     ../source/samples/dom/wrappers
-
-#-samples/sax
-
-	${MKDIR} ../source/samples/sax
-	${CP}  ../samples/sax/*.java  ../source/samples/sax
-
-#-samples/sax/helpers
-
-	${MKDIR}  ../source/samples/sax/helpers
-	${CP}  ../samples/sax/helpers/*.java                      ../source/samples/sax/helpers
-
-#-samples/ui
-
-	${MKDIR}  ../source/samples/ui
-	${CP}  ../samples/ui/*.java  ../source/samples/ui
-
-
-#-samples/util
-
-	${MKDIR}  ../source/samples/util
-	${CP}  ../samples/util/*.java  ../source/samples/util
-
-
-
-#########################################
-#copy the Makefiles under src
-
-#-src/org/apache/xerces/dom
-	${CP}  ../src/org/apache/xerces/dom/Makefile  			../source/src/org/apache/xerces/dom
-
-#-src/org/apache/xerces/dom/events
-	${CP}  ../src/org/apache/xerces/dom/events/Makefile  		../source/src/org/apache/xerces/dom/events
-
-#-src/org/apache/xerces/framework
-	${CP}  ../src/org/apache/xerces/framework/Makefile		../source/src/org/apache/xerces/framework
-
-#-src/org/apache/xerces/infoset
-#	${MKDIR} ../source/src/org/apache/xerces/infoset
-#	${CP}  ../src/org/apache/xerces/infoset/Makefile			../source/src/org/apache/xerces/infoset
-
-#-src/org/apache/xerces/internal/msg
-#	${CP}  ../src/org/apache/xerces/internal/msg/Makefile		../source/src/org/apache/xerces/internal/msg
-
-#-src/org/apache/xerces/msg
-	${CP}  ../src/org/apache/xerces/msg/Makefile                      ../source/src/org/apache/xerces/msg
-
-#-src/org/apache/xerces/parsers
-	${CP}  ../src/org/apache/xerces/parsers/Makefile			../source/src/org/apache/xerces/parsers
-
-#-src/org/apache/xerces/readers
-	${CP}  ../src/org/apache/xerces/readers/Makefile                  ../source/src/org/apache/xerces/readers
-
-#-src/org/apache/xerces/utils
-	${CP}  ../src/org/apache/xerces/utils/Makefile                    ../source/src/org/apache/xerces/utils
-
-#-src/org/apache/xerces/utils/regex
-	${CP}  ../src/org/apache/xerces/utils/regex/Makefile                    ../source/src/org/apache/xerces/utils/regex
-
-#-src/org/apache/xerces/validaters/common
-	${CP}  ../src/org/apache/xerces/validators/common/Makefile      ../source/src/org/apache/xerces/validators/common
-
-#-src/org/apache/xerces/validaters/datatype
-	${CP}  ../src/org/apache/xerces/validators/datatype/Makefile      ../source/src/org/apache/xerces/validators/datatype
-
-#-src/org/apache/xerces/validaters/dtd
-	${CP}  ../src/org/apache/xerces/validators/dtd/Makefile           ../source/src/org/apache/xerces/validators/dtd
-
-#-src/org/apache/xerces/validaters/schema
-	${CP}  ../src/org/apache/xerces/validators/schema/Makefile        ../source/src/org/apache/xerces/validators/schema
-
-#-src/org/apache/xml/serialize
-	${CP}  ../src/org/apache/xml/serialize/Makefile                    ../source/src/org/apache/xml/serialize
-
-#-src/org/w3c/dom
-	${CP}  ../src/org/w3c/dom/Makefile				../source/src/org/w3c/dom
-
-#-src/org/w3c/dom/events
-	${CP}  ../src/org/w3c/dom/events/Makefile 			../source/src/org/w3c/dom/events
-#-src/org/w3c/dom/range
-	${CP}  ../src/org/w3c/dom/range/Makefile			../source/src/org/w3c/dom/range
-
-#-src/org/w3c/dom/html
-	${CP}  ../src/org/w3c/dom/html/Makefile				../source/src/org/w3c/dom/html
-
-#-src/org/w3c/dom/traversal
-	${CP}  ../src/org/w3c/dom/traversal/Makefile			../source/src/org/w3c/dom/traversal
-
-#-src/org/xml/sax
-	${CP}  ../src/org/xml/sax/Makefile				../source/src/org/xml/sax
-
-#-src/org/xml/sax/helpers
-	${CP}  ../src/org/xml/sax/helpers/Makefile			../source/src/org/xml/sax/helpers
-
-#-src/org/xml/sax/ext
-	${CP}  ../src/org/xml/sax/ext/Makefile			../source/src/org/xml/sax/ext
-
-#-src/org/apache/wml
-	${CP}  ../src/org/apache/wml/Makefile                  ../source/src/org/apache/wml
-	${CP}  ../src/org/apache/wml/dom/Makefile                  ../source/src/org/apache/wml/dom
-
-
-
-###
-#copy the Makefiles and the batch files at higher levels
-#-source
-	${CP}  ../Makefile    ../source
-
-#-src
-	${CP}  ../src/Makefile    ../source/src
-
-#-src
-	${CP}  ../src/Makefile.incl    ../source/src
-
-#-src/org
-	${CP}  ../src/org/Makefile    ../source/src/org
-
-#-src/org/apache
-	${CP}  ../src/org/apache/Makefile    ../source/src/org/apache
-
-#-src/org/apache/html
-	${CP}  ../src/org/apache/html/Makefile    ../source/src/org/apache/html
-
-#-src/org/apache/html/dom
-	${CP}  ../src/org/apache/html/dom/Makefile    ../source/src/org/apache/html/dom
-
-#-src/org/apache/xerces
-	${CP}  ../src/org/apache/xerces/Makefile    ../source/src/org/apache/xerces
-
-#-src/org/apache/xerces/domx
-	${CP}  ../src/org/apache/xerces/domx/Makefile    ../source/src/org/apache/xerces/domx
-
-#-src/org/apache/xerces/internal
-#	${CP}  ../src/org/apache/xerces/internal/Makefile    ../source/src/org/apache/xerces/internal
-
-#-src/org/apache/xerces/validators
-	${CP}  ../src/org/apache/xerces/validators/Makefile    ../source/src/org/apache/xerces/validators
-
-#-src/org/apache/xml
-	${CP}  ../src/org/apache/xml/Makefile    ../source/src/org/apache/xml
-
-#-src/org
-	${CP}  ../src/org/Makefile    ../source/src/org
-
-#-src/org/w3c
-	${CP}  ../src/org/w3c/Makefile    ../source/src/org/w3c
-
-#-src/org/xml
-	${CP}  ../src/org/xml/Makefile    ../source/src/org/xml
-
-
-#-src/javax/xml/parsers
-	${CP}  ../src/javax/xml/parsers/Makefile    ../source/src/javax/xml/parsers
-
-#-src/javax/xml
-	${CP}  ../src/javax/xml/Makefile    ../source/src/javax/xml
-
-#-src/javax
-	${CP}  ../src/javax/Makefile    ../source/src/javax
-
-#-src/org/apache/xerces/jaxp
-	${CP}  ../src/org/apache/xerces/jaxp/Makefile    ../source/src/org/apache/xerces/jaxp
-
-###################################
-#copy the Makefiles under samples
-
-#-samples/dom
-
-	${CP}  ../samples/dom/Makefile  ../source/samples/dom
-
-#-samples/dom/traversal
-
-	${CP}  ../samples/dom/traversal/Makefile                    ../source/samples/dom/traversal
-
-#-samples/dom/wrappers
-
-	${CP}  ../samples/dom/wrappers/Makefile                     ../source/samples/dom/wrappers
-
-#-samples/sax
-
-	${CP}  ../samples/sax/Makefile  ../source/samples/sax
-
-#-samples/sax/helpers
-
-	${CP}  ../samples/sax/helpers/Makefile                      ../source/samples/sax/helpers
-
-#-samples/ui
-
-	${MKDIR}  ../source/samples/ui
-	${CP}  ../samples/ui/Makefile  ../source/samples/ui
-
-#-samples/util
-
-	${MKDIR}  ../source/samples/util
-	${CP}  ../samples/util/Makefile  ../source/samples/util
-
-
-###
-#copy higher levels Makefiles
-
-#-samples
-	${CP}  ../samples/Makefile  ../source/samples
-
-# copy the license, ANT build file, Status file, and READMEs
-	${CP}  ../README ../Readme.html ../STATUS ../source
diff --git a/src/Makefile.incl b/src/Makefile.incl
deleted file mode 100644
index 7971993..0000000
--- a/src/Makefile.incl
+++ /dev/null
@@ -1,107 +0,0 @@
-# Decide if we're on unix or DOS
-ifneq ($(findstring WIN,$(shell uname)),)
-# DOS
-CLPATHSEP := ;
-else 
-# UNIX
-CLPATHSEP := :
-endif
-
-#
-# Define the environment commands and/or utilities
-#
-XERCES_CLASSPATH = $(TOP)/src$(CLPATHSEP)$(TOP)/samples
-CLPATH = $(XERCES_CLASSPATH)$(CLPATHSEP)$(CLASSPATH)
-
-STYLEBOOK_CLPATH = $(TOP)/tools/xalan.jar$(CLPATHSEP)$(TOP)/tools/xerces.jar$(CLPATHSEP)$(XERCES_CLASSPATH)$(CLPATHSEP)$(TOP)/tools/stylebook-1.0-b2.jar
-
-SB_CLPATH = $(STYLEBOOK_CLPATH)$(CLPATHSEP)$(CLASSPATH)
-
-JAR = jar
-JAVAC = javac
-ifeq ($(JDK12BIN),)
-JAVA12 = java
-JAVADOC12 = javadoc
-else
-JAVA12 = $(JDK12BIN)/java
-JAVADOC12 = $(JDK12BIN)/javadoc
-endif
-STYLEBOOK = $(JAVA12) -classpath "$(SB_CLPATH)" org.apache.stylebook.StyleBook
-
-MKDIR = mkdir -p 
-RM = -rm -f
-CP = cp
-MV = mv
-
-#
-# Define the version strings
-#
-PRODUCTVERSION = 1_2_0
-PRODUCTVERSION_DOT = 1.2.0
-PRODUCTNAME = Xerces
-
-#define the jar file names
-
-JARFILE = xerces.jar
-SAMPLESJARFILE = xercesSamples.jar
-
-#define the package value	
-PACKAGES = \
-	org.apache.xerces.framework \
-	org.apache.xerces.parsers \
-	org.apache.xerces.dom \
-	org.apache.xerces.dom.events \
-	org.apache.xml.serialize \
-	org.apache.html.dom \
-	org.apache.wml \
-	org.apache.wml.dom \
-	org.w3c.dom \
-	org.w3c.dom.events \
-	org.w3c.dom.range \
-	org.w3c.dom.traversal \
-	org.w3c.dom.html \
-	org.xml.sax \
-	org.xml.sax.ext \
-	org.xml.sax.helpers \
-	javax.xml.parsers
-
-
-BINZIPFILE = ${PRODUCTNAME}-J-bin.${PRODUCTVERSION_DOT}.zip
-SRCZIPFILE = ${PRODUCTNAME}-J-src.${PRODUCTVERSION_DOT}.zip
-
-BINTARFILE = ${PRODUCTNAME}-J-bin.${PRODUCTVERSION_DOT}.tar
-SRCTARFILE = ${PRODUCTNAME}-J-src.${PRODUCTVERSION_DOT}.tar
-
-BINJARFILE = ${PRODUCTNAME}-J-bin.${PRODUCTVERSION_DOT}.jar
-SRCJARFILE = ${PRODUCTNAME}-J-src.${PRODUCTVERSION_DOT}.jar
-
-# Common rules
-
-.SUFFIXES: .class .java
-
-.java.class:
-	${JAVAC} -classpath "$(CLPATH)" $<
-	touch ${TOP}/src/classfiles_updated
-
-all:: dirs compile 
-
-compile:: ${TARGETS}
-
-clean:: cleandirs
-	@$(RM) *.class
-
-dirs::
-	@if [ -n "$(DIRS)" ]; \
-	then for i in $(DIRS) __bogus__; do \
-	       if [ $$i != __bogus__ ] ; then \
-		echo "$(MAKE) -C $$i"; $(MAKE) -C $$i; \
-		fi \
-	     done; \
-	fi
-
-cleandirs::
-	@if [ -n "$(DIRS)" ]; \
-	then for i in $(DIRS);do \
-		echo "$(MAKE) -C $$i clean"; $(MAKE) -C $$i clean; \
-	     done; \
-	fi
diff --git a/src/classfiles_updated b/src/classfiles_updated
deleted file mode 100644
index e69de29..0000000
--- a/src/classfiles_updated
+++ /dev/null
diff --git a/src/javax/Makefile b/src/javax/Makefile
deleted file mode 100644
index 4e5b449..0000000
--- a/src/javax/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Makefile for directory ./javax
-
-TARGETS =
-
-DIRS = xml
-
-TOP = ../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/javax/xml/Makefile b/src/javax/xml/Makefile
deleted file mode 100644
index 0a657df..0000000
--- a/src/javax/xml/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Makefile for directory ./javax/xml
-
-TARGETS =
-
-DIRS = parsers
-
-TOP = ../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/javax/xml/parsers/DocumentBuilder.java b/src/javax/xml/parsers/DocumentBuilder.java
deleted file mode 100644
index c0189c0..0000000
--- a/src/javax/xml/parsers/DocumentBuilder.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999-2000, Pierpaolo
- * Fumagalli <mailto:pier@betaversion.org>, http://www.apache.org.
- * For more information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package javax.xml.parsers;
-
-import java.io.File;
-import java.io.InputStream;
-import java.io.IOException;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.w3c.dom.Document;
-
-/**
- * Instances of <code>DocumentBuilder</code> provide a mechansim for
- * parsing XML documents into a DOM document tree represented by an
- * <code>org.w3c.dom.Document</code> object.
- * <br>
- * A <code>DocumentBuilder</code> instance is obtained from a
- * <code>DocumentBuilderFactory</code> by invoking its
- * <code>newDocumentBuilder()</code> method.
- * <br>
- * <b>NOTE:</b> <code>DocumentBuilder</code> uses several classes from the
- *     SAX API. This does not require that the implementor of the
- *     underlying DOM implementation use a SAX parser to parse XML content
- *     into a <code>org.w3c.dom.Document</code>. It merely requires that
- *     the implementation communicate with the application using these
- *     existing APIs.
- * <br>
- * <br>
- * <b>ATTENTION:</b> THIS IMPLEMENTATION OF THE "JAVAX.XML.PARSER" CLASSES
- *   IS NOT THE OFFICIAL REFERENCE IMPLEMENTATION OF THE JAVA SPECIFICATION
- *   REQUEST 5 FOUND AT
- *   <a href="http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html">
- *   http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html
- *   </a><br>
- *   THIS IMPLEMENTATION IS CONFORMANT TO THE "JAVA API FOR XML PARSING"
- *   SPECIFICATION VERSION 1.0 PUBLIC RELEASE 1 BY JAMES DUNCAN DAVIDSON
- *   PUBLISHED BY SUN MICROSYSTEMS ON FEB. 18, 2000 AND FOUND AT
- *   <a href="http://java.sun.com/xml">http://java.sun.com/xml</a>
- * <br>
- * <br>
- * <b>THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author <a href="pier@betaversion.org">Pierpaolo Fumagalli</a>
- * @author Copyright &copy; 2000 The Apache Software Foundation.
- * @version 1.0 CVS $Revision$ $Date$
- */
-public abstract class DocumentBuilder {
-
-    /**
-     * Implementors of this abstract class are not required to provide a
-     * public no-argument constructor, since instantiation is taken care
-     * by <code>DocumentBuilderFactory</code> implementations.
-     */
-    protected DocumentBuilder() {
-        super();
-    }
-
-    /**
-     * Parses the contents of the given <code>InputStream</code> and returns
-     * a <code>Document</code> object.
-     *
-     * @exception SAXException If there is a problem parsing the given XML
-     *                content.
-     * @exception IOException If any IO errors occur reading the given
-     *                <code>InputStream</code>.
-     * @exception  IllegalArgumentException If the given
-     *                <code>InputStream</code> is <b>null</b>.
-     */
-    public Document parse(InputStream stream)
-    throws SAXException, IOException, IllegalArgumentException {
-        if (stream==null) throw new IllegalArgumentException();
-        return(this.parse(new InputSource(stream)));
-    }
-
-    /**
-     * Parses the content of the given URI and returns a <code>Document</code>
-     * object.
-     *
-     * @exception SAXException If there is a problem parsing the given XML
-     *                content.
-     * @exception IOException If any IO errors occur while reading content
-     *                located by the given URI.
-     * @exception IllegalArgumentException If the given URI is <b>null</b>.
-     */
-    public Document parse(String uri)
-    throws SAXException, IOException, IllegalArgumentException {
-        if (uri==null) throw new IllegalArgumentException();
-        return(this.parse(new InputSource(uri)));
-    }
-
-    /**
-     * Parses the content of the given <code>File</code> and returns a
-     * <code>Document</code> object.
-     *
-     * @exception SAXException If there is a problem parsing the given XML
-     *                content.
-     * @exception IOException if any IO errors occur while reading content
-     *                from the given <code>File</code>.
-     * @exception IllegalArgumentException if the given <code>File</code> is
-     *                <b>null</b>.
-     */
-    public Document parse(File file)
-    throws SAXException, IOException, IllegalArgumentException {
-        if (file==null) throw new IllegalArgumentException();
-        // Thanks to Kevin Kress <Kevin.Kress@oracle.com> for pointing
-        // out this bug.
-        return(this.parse(new InputSource(file.getAbsolutePath())));
-    }
-
-    /**
-     * Parses the content of the given <code>InputSource</code> and returns
-     * a <code>Document</code> object.
-     *
-     * @exception SAXException If there is a problem parsing the given XML
-     *                content.
-     * @exception IOException if any IO Errors occur while reading content
-     *                from the given <code>InputSource</code>.
-     * @exception IllegalArgumentException if the given
-     *                <code>InputSource</code> is <b>null</b>.
-     */
-    public abstract Document parse(InputSource source)
-    throws SAXException, IOException, IllegalArgumentException;
-
-    /**
-     * Creates an new <code>Document</code> instance from the underlying DOM
-     * implementation.
-     */
-    public abstract Document newDocument();
-
-    /**
-     * Returns whether or not this parser supports XML namespaces.
-     */
-    public abstract boolean isNamespaceAware();
-
-    /**
-     * Returns whether or not this parser supports validating XML content.
-     */
-    public abstract boolean isValidating();
-
-    /**
-     * Specifies the <code>EntityResolver</code> to be used by this
-     * <code>DocumentBuilder</code>.
-     * <br>
-     * Setting the <code>EntityResolver</code> to <b>null</b>, or not
-     * calling this method, will cause the underlying implementation to
-     * use its own default implementation and behavior.
-     */
-    public abstract void setEntityResolver(EntityResolver er);
-
-    /**
-     * Specifies the <code>ErrorHandler</code> to be used by this
-     * <code>DocumentBuilder</code>.
-     *
-     * Setting the <code>ErrorHandler</code> to <b>null</b>, or not
-     * calling this method, will cause the underlying implementation to
-     * use its own default implementation and behavior.
-     */
-    public abstract void setErrorHandler(ErrorHandler eh);
-}
-
diff --git a/src/javax/xml/parsers/DocumentBuilderFactory.java b/src/javax/xml/parsers/DocumentBuilderFactory.java
deleted file mode 100644
index 4e0bc3e..0000000
--- a/src/javax/xml/parsers/DocumentBuilderFactory.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999-2000, Pierpaolo
- * Fumagalli <mailto:pier@betaversion.org>, http://www.apache.org.
- * For more information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package javax.xml.parsers;
-
-/**
- * The <code>DocumentBuilderFactory</code> defines a factory API that enables
- * applications to configure and obtain a parser to parse XML documents into
- * a DOM Document tree.
- * <br>
- * <br>
- * <b>ATTENTION:</b> THIS IMPLEMENTATION OF THE "JAVAX.XML.PARSER" CLASSES
- *   IS NOT THE OFFICIAL REFERENCE IMPLEMENTATION OF THE JAVA SPECIFICATION
- *   REQUEST 5 FOUND AT
- *   <a href="http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html">
- *   http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html
- *   </a><br>
- *   THIS IMPLEMENTATION IS CONFORMANT TO THE "JAVA API FOR XML PARSING"
- *   SPECIFICATION VERSION 1.0 PUBLIC RELEASE 1 BY JAMES DUNCAN DAVIDSON
- *   PUBLISHED BY SUN MICROSYSTEMS ON FEB. 18, 2000 AND FOUND AT
- *   <a href="http://java.sun.com/xml">http://java.sun.com/xml</a>
- * <br>
- * <br>
- * <b>THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author <a href="pier@betaversion.org">Pierpaolo Fumagalli</a>
- * @author Copyright &copy; 2000 The Apache Software Foundation.
- * @version 1.0 CVS $Revision$ $Date$
- */
-public abstract class DocumentBuilderFactory {
-
-    /** Wether the DocumentBuilder to be generated must support namespaces. */
-    private boolean namespaces=false;
-    /** Wether the DocumentBuilder to be generated must support validataion. */
-    private boolean validation=false;
-    /** The system property to check for DocumentBuilderFactory class name. */
-    private static String property="javax.xml.parsers.DocumentBuilderFactory";
-    /** The default DocumentBuilderFactory implementation class name. */
-    private static String factory=
-                          "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl";
-
-    /**
-     * Implementors of this abstract class <b>must</b> provide their own
-     * public no-argument constructor in order for the static
-     * <code>newInstance()</code> method to work correctly.
-     * <br>
-     * Application programmers should be able to instantiate an implementation
-     * of this abstract class directly if they want to use a specfic
-     * implementation of this API without using the static newInstance method
-     * to obtain the configured or platform default implementation.
-     */
-    protected DocumentBuilderFactory() {
-        super();
-    }
-
-    /**
-     *
-     * Returns a new instance of a <code>DocumentBuilderFactory</code>.
-     * <br>
-     * The implementation of the <code>DocumentBuilderFactory</code>
-     * returned depends on the setting of the
-     * <code>javax.xml.parsers.DocumentBuilderFactory</code> property or,
-     * if the property is not set, a platform specific default.
-     *
-     * @exception FactoryConfigurationError If the class implementing the
-     *                factory cannot be found or instantiated.
-     *                An <code>Error</code> is thrown instead of an exception
-     *                because the application is not expected to handle or
-     *                recover from such events.
-     */
-    public static DocumentBuilderFactory newInstance() {
-
-        // Retrieve the javax.xml.parsers.DocumentBuilderFactory system property
-        String n=factory;
-        try {
-            n=System.getProperty(property, factory);
-        } catch (SecurityException e) {
-        	// In applets System.getProperty throws a SecurityException.
-        	// Thanks to Aaron Buchanan <abuchanan@inovacorp.com> and to
-        	// James Duncan Davidson <james.davidson@eng.sun.com> for this
-        	n=factory;
-        }
-
-        try {
-            // Attempt to load, instantiate and return the factory class
-            return (DocumentBuilderFactory)Class.forName(n).newInstance();
-
-        } catch (ClassNotFoundException e) {
-            // The factory class was not found
-            throw new FactoryConfigurationError("Cannot load class "+
-                "DocumentBuilderFactory class \""+n+"\"");
-
-        } catch (InstantiationException e) {
-            // The factory class wasn't instantiated
-            throw new FactoryConfigurationError("Cannot instantiate the "+
-                "specified DocumentBuilderFactory class \""+n+"\"");
-
-        } catch (IllegalAccessException e) {
-            // The factory class couldn't have been accessed
-            throw new FactoryConfigurationError("Cannot access the specified "+
-                "DocumentBuilderFactory class \""+n+"\"");
-
-        } catch (ClassCastException e) {
-            // The factory class was not a DocumentBuilderFactory
-            throw new FactoryConfigurationError("The specified class \""+n+
-                "\" is not instance of \""+
-                "javax.xml.parsers.DocumentBuilderFactory\"");
-        }
-    }
-
-    /**
-     * Returns a new configured instance of type <code>DocumentBuilder</code>.
-     *
-     * @exception ParserConfigurationException If the
-     *                <code>DocumentBuilder</code> instance cannot be created
-     *                with the requested configuration.
-     */
-    public abstract DocumentBuilder newDocumentBuilder()
-    throws ParserConfigurationException;
-
-    /**
-     * Configuration method that specifies whether the parsers created by this
-     * factory are required to provide XML namespace support or not.
-     * <br>
-     * <b>NOTE:</b> if a parser cannot be created by this factory that
-     *     satisfies the requested namespace awareness value, a
-     *     <code>ParserConfigurationException</code> will be thrown when the
-     *     program attempts to aquire the parser calling the
-     *     <code>newDocumentBuilder()</code> method.
-     */
-    public void setNamespaceAware(boolean aware) {
-        this.namespaces=aware;
-    }
-
-    /**
-     * Configuration method whether specifies if the parsers created by this
-     * factory are required to validate the XML documents that they parse.
-     * <br>
-     * <b>NOTE:</b> if a parser cannot be created by this factory that
-     *     satisfies the requested validation capacity, a
-     *     <code>ParserConfigurationException</code> will be thrown when
-     *     the application attempts to aquire the parser via the
-     *     <code>newDocumentBuilder()</code> method.
-     */
-    public void setValidating(boolean validating) {
-        this.validation=validating;
-    }
-
-    /**
-     * Indicates if this <code>DocumentBuilderFactory</code> is configured to
-     * produce parsers that are namespace aware or not.
-     */
-    public boolean isNamespaceAware() {
-        return(this.namespaces);
-    }
-
-    /**
-     * Indicates if this <code>DocumentBuilderFactory</code> is configured to
-     * produce parsers that validate XML documents as they are parsed.
-     */
-    public boolean isValidating() {
-        return(this.validation);
-    }
-}
diff --git a/src/javax/xml/parsers/FactoryConfigurationError.java b/src/javax/xml/parsers/FactoryConfigurationError.java
deleted file mode 100644
index 378cb56..0000000
--- a/src/javax/xml/parsers/FactoryConfigurationError.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999-2000, Pierpaolo
- * Fumagalli <mailto:pier@betaversion.org>, http://www.apache.org.
- * For more information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package javax.xml.parsers;
-
-/**
- * This error is thrown if there is a configuration problem when creating
- * new factory instances.
- * <br>
- * This error will also be thrown when the class of a Factory specified by
- * a system property, or the class of the default system parser factory,
- * cannot be loaded or instantiated.
- * <br>
- * Implementation or Application developers should never need to directly
- * construct or catch errors of this type.
- * <br>
- * <br>
- * <b>ATTENTION:</b> THIS IMPLEMENTATION OF THE "JAVAX.XML.PARSER" CLASSES
- *   IS NOT THE OFFICIAL REFERENCE IMPLEMENTATION OF THE JAVA SPECIFICATION
- *   REQUEST 5 FOUND AT
- *   <a href="http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html">
- *   http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html
- *   </a><br>
- *   THIS IMPLEMENTATION IS CONFORMANT TO THE "JAVA API FOR XML PARSING"
- *   SPECIFICATION VERSION 1.0 PUBLIC RELEASE 1 BY JAMES DUNCAN DAVIDSON
- *   PUBLISHED BY SUN MICROSYSTEMS ON FEB. 18, 2000 AND FOUND AT
- *   <a href="http://java.sun.com/xml">http://java.sun.com/xml</a>
- * <br>
- * <br>
- * <b>THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author <a href="pier@betaversion.org">Pierpaolo Fumagalli</a>
- * @author Copyright &copy; 2000 The Apache Software Foundation.
- * @version 1.0 CVS $Revision$ $Date$
- */
-public class FactoryConfigurationError extends Error {
-
-    /** The root cause of this <code>FactoryConfigurationError</code>. */
-    private Exception exception=null;
-
-    /**
-     * Constructs a new <code>FactoryConfigurationError</code> with no
-     * detail message.
-     */
-    public FactoryConfigurationError() {
-        this(null,null);
-    }
-
-    /**
-     * Constructs a new <code>FactoryConfigurationError</code> with the
-     * given detail message.
-     */
-    public FactoryConfigurationError(String msg) {
-        this(null,msg);
-    }
-
-    /**
-     * Constructs a new <code>FactoryConfigurationError</code> with the
-     * given <code>Exception</code> as a root cause.
-     */
-    public FactoryConfigurationError(Exception e) {
-        this(e,null);
-    }
-
-    /**
-     * Constructs a new <code>FactoryConfigurationError</code> with the
-     * given <code>Exception</code> as a root cause and the given detail
-     * message.
-     */
-    public FactoryConfigurationError(Exception e, String msg) {
-        super(msg);
-        this.exception=e;
-    }
-
-    /**
-     * Returns the root cause of this <code>FactoryConfigurationError</code>
-     * or <b>null</b> if there is none.
-     */
-    public Exception getException() {
-        return(this.exception);
-    }
-}
diff --git a/src/javax/xml/parsers/Makefile b/src/javax/xml/parsers/Makefile
deleted file mode 100644
index b708128..0000000
--- a/src/javax/xml/parsers/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# Makefile for directory ./javax/xml
-
-TARGETS =\
-        DocumentBuilder.class\
-        DocumentBuilderFactory.class\
-        FactoryConfigurationError.class\
-        ParserConfigurationException.class\
-        SAXParser.class\
-        SAXParserFactory.class
-
-DIRS =
-
-TOP = ../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/javax/xml/parsers/ParserConfigurationException.java b/src/javax/xml/parsers/ParserConfigurationException.java
deleted file mode 100644
index d21a6f5..0000000
--- a/src/javax/xml/parsers/ParserConfigurationException.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999-2000, Pierpaolo
- * Fumagalli <mailto:pier@betaversion.org>, http://www.apache.org.
- * For more information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package javax.xml.parsers;
-
-/**
- * This exception is thrown if a factory cannot configure a parser given its
- * current configuration parameters.
- * <br>
- * For example, if a parser factory cannot create parsers that validate,
- * but have been configured to do so, it will throw this exception when a
- * parser is requested to via the parser creation methods.
- * <br>
- * Application developers are not expected to construct instances of this
- * exception type, but must catch them in code that obtains parser instances
- * from a factory.
- * <br>
- * <br>
- * <b>ATTENTION:</b> THIS IMPLEMENTATION OF THE "JAVAX.XML.PARSER" CLASSES
- *   IS NOT THE OFFICIAL REFERENCE IMPLEMENTATION OF THE JAVA SPECIFICATION
- *   REQUEST 5 FOUND AT
- *   <a href="http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html">
- *   http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html
- *   </a><br>
- *   THIS IMPLEMENTATION IS CONFORMANT TO THE "JAVA API FOR XML PARSING"
- *   SPECIFICATION VERSION 1.0 PUBLIC RELEASE 1 BY JAMES DUNCAN DAVIDSON
- *   PUBLISHED BY SUN MICROSYSTEMS ON FEB. 18, 2000 AND FOUND AT
- *   <a href="http://java.sun.com/xml">http://java.sun.com/xml</a>
- * <br>
- * <br>
- * <b>THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author <a href="pier@betaversion.org">Pierpaolo Fumagalli</a>
- * @author Copyright &copy; 2000 The Apache Software Foundation.
- * @version 1.0 CVS $Revision$ $Date$
- */
-public class ParserConfigurationException extends Exception {
-
-    /**
-     * Constructs a new <code>ParserConfigurationException</code> with no
-     * detail message.
-     */
-    public ParserConfigurationException() {
-        super();
-    }
-
-    /**
-     * Constructs a new <code>ParserConfigurationException</code> with the
-     * given detail message.
-     */
-    public ParserConfigurationException(String msg) {
-        super(msg);
-    }
-}
diff --git a/src/javax/xml/parsers/SAXParser.java b/src/javax/xml/parsers/SAXParser.java
deleted file mode 100644
index 8b80e6a..0000000
--- a/src/javax/xml/parsers/SAXParser.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999-2000, Pierpaolo
- * Fumagalli <mailto:pier@betaversion.org>, http://www.apache.org.
- * For more information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package javax.xml.parsers;
-
-import java.io.File;
-import java.io.InputStream;
-import java.io.IOException;
-import org.xml.sax.HandlerBase;
-import org.xml.sax.InputSource;
-import org.xml.sax.Parser;
-import org.xml.sax.SAXException;
-
-/**
- * Implementation instances of the <code>SAXParser</code> abstract class
- * contain an implementation of the <code>org.xml.sax.Parser</code> interface
- * and enables content from a variety of sources to be parsed using the
- * contained parser.
- * <br>
- * Instances of <code>SAXParser</code> are obtained from a
- * <code>SAXParserFactory</code> by invoking its <code>newSAXParser()</code>
- * method.
- * <br>
- * <br>
- * <b>ATTENTION:</b> THIS IMPLEMENTATION OF THE "JAVAX.XML.PARSER" CLASSES
- *   IS NOT THE OFFICIAL REFERENCE IMPLEMENTATION OF THE JAVA SPECIFICATION
- *   REQUEST 5 FOUND AT
- *   <a href="http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html">
- *   http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html
- *   </a><br>
- *   THIS IMPLEMENTATION IS CONFORMANT TO THE "JAVA API FOR XML PARSING"
- *   SPECIFICATION VERSION 1.0 PUBLIC RELEASE 1 BY JAMES DUNCAN DAVIDSON
- *   PUBLISHED BY SUN MICROSYSTEMS ON FEB. 18, 2000 AND FOUND AT
- *   <a href="http://java.sun.com/xml">http://java.sun.com/xml</a>
- * <br>
- * <br>
- * <b>THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author <a href="pier@betaversion.org">Pierpaolo Fumagalli</a>
- * @author Copyright &copy; 2000 The Apache Software Foundation.
- * @version 1.0 CVS $Revision$ $Date$
- */
-public abstract class SAXParser {
-
-    /**
-     * Implementations should provide a protected constructor so that 
-     * their factory implementation can instantiate instances of the 
-     * implementation class.
-     * <br>
-     * Application programmers should not be able to directly construct 
-     * implementation subclasses of this abstract subclass. The only way a 
-     * application should be able to obtain a reference to a SAXParser 
-     * implementation instance is by using the appropriate methods of the 
-     * <code>SAXParserFactory</code>.
-     */
-    protected SAXParser() {
-        super();
-    }
-
-    /**
-     * Parses the contents of the given <code>InputStream</code> as an XML
-     * document using the specified <code>HandlerBase</code> object.
-     *
-     * @exception SAXException If there is a problem parsing the given XML
-     *                content.
-     * @exception IOException If any IO errors occur reading the given
-     *                <code>InputStream</code>.
-     * @exception  IllegalArgumentException If the given
-     *                <code>InputStream</code> is <b>null</b>.
-     */
-    public void parse(InputStream stream, HandlerBase base)
-    throws SAXException, IOException, IllegalArgumentException {
-        if (stream==null) throw new IllegalArgumentException();
-        this.parse(new InputSource(stream),base);
-    }
-
-    /**
-     * Parses the content of the given URI as an XML document using the
-     * specified <code>HandlerBase</code> object.
-     *
-     * @exception SAXException If there is a problem parsing the given XML
-     *                content.
-     * @exception IOException If any IO errors occur while reading content
-     *                located by the given URI.
-     * @exception IllegalArgumentException If the given URI is <b>null</b>.
-     */
-    public void parse(String uri, HandlerBase base)
-    throws SAXException, IOException, IllegalArgumentException {
-        if (uri==null) throw new IllegalArgumentException();
-        this.parse(new InputSource(uri),base);
-    }
-
-    /**
-     * Parses the content of the given <code>File</code> as an XML document
-     * using the specified <code>HandlerBase</code> object.
-     *
-     * @exception SAXException If there is a problem parsing the given XML
-     *                content.
-     * @exception IOException if any IO errors occur while reading content
-     *                from the given <code>File</code>.
-     * @exception IllegalArgumentException if the given <code>File</code> is
-     *                <b>null</b>.
-     */
-    public void parse(File file, HandlerBase base)
-    throws SAXException, IOException, IllegalArgumentException {
-        if (file==null) throw new IllegalArgumentException();
-        String path = file.getAbsolutePath();
-        if (File.separatorChar != '/') {
-            path = path.replace(File.separatorChar, '/');
-        }
-        if (!path.startsWith("/")) {
-            path = "/" + path;
-        }
-        if (!path.endsWith("/") && file.isDirectory()) {
-            path = path + "/";
-        }
-        java.net.URL url = new java.net.URL("file", "", path);
-        this.parse(new InputSource(url.toString()),base);
-    }
-
-    /**
-     * Parses the content of the given <code>InputSource</code> as an XML
-     * document using the specified <code>HandlerBase</code> object.
-     *
-     * @exception SAXException If there is a problem parsing the given XML
-     *                content.
-     * @exception IOException if any IO Errors occur while reading content
-     *                from the given <code>InputSource</code>.
-     * @exception IllegalArgumentException if the given
-     *                <code>InputSource</code> is <b>null</b>.
-     */
-    public void parse(InputSource source, HandlerBase base)
-    throws SAXException, IOException, IllegalArgumentException {
-        if (source==null) throw new IllegalArgumentException();
-
-        // Get the SAX parser instance
-        Parser p=this.getParser();
-
-        // Set the various handler instances
-        if (base!=null) {
-            p.setDocumentHandler(base);
-            p.setDTDHandler(base);
-            p.setEntityResolver(base);
-            p.setErrorHandler(base);
-        }
-
-        // Parse the specified source
-        p.parse(source);
-    }
-
-    /**
-     * Returns the underlying <code>Parser</code> object which is wrapped by
-     * this <code>SAXParser</code> implementation.
-     *
-     * @exception SAXException If the initialization of the underlying parser
-     *                fails. <b>NOTE:</b> This Exception is specified on page
-     *                21 of the specification, but later on omissed in this
-     *                method documentation on page 23. Wich one is correct?
-     */
-    public abstract Parser getParser()
-    throws SAXException;
-
-    /**
-     * Returns whether or not this parser supports XML namespaces.
-     */
-    public abstract boolean isNamespaceAware();
-
-    /**
-     * Returns whether or not this parser supports validating XML content.
-     */
-    public abstract boolean isValidating();
-}
diff --git a/src/javax/xml/parsers/SAXParserFactory.java b/src/javax/xml/parsers/SAXParserFactory.java
deleted file mode 100644
index 944ceeb..0000000
--- a/src/javax/xml/parsers/SAXParserFactory.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999-2000, Pierpaolo
- * Fumagalli <mailto:pier@betaversion.org>, http://www.apache.org.
- * For more information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package javax.xml.parsers;
-
-import org.xml.sax.SAXException;
-
-/**
- * The <code>SAXParserFactory</code> defines a factory API that enables
- * applications to configure and obtain a SAX based parser to parse XML
- * documents.
- * <br>
- * <br>
- * <b>ATTENTION:</b> THIS IMPLEMENTATION OF THE "JAVAX.XML.PARSER" CLASSES
- *   IS NOT THE OFFICIAL REFERENCE IMPLEMENTATION OF THE JAVA SPECIFICATION
- *   REQUEST 5 FOUND AT
- *   <a href="http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html">
- *   http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html
- *   </a><br>
- *   THIS IMPLEMENTATION IS CONFORMANT TO THE "JAVA API FOR XML PARSING"
- *   SPECIFICATION VERSION 1.0 PUBLIC RELEASE 1 BY JAMES DUNCAN DAVIDSON
- *   PUBLISHED BY SUN MICROSYSTEMS ON FEB. 18, 2000 AND FOUND AT
- *   <a href="http://java.sun.com/xml">http://java.sun.com/xml</a>
- * <br>
- * <br>
- * <b>THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author <a href="pier@betaversion.org">Pierpaolo Fumagalli</a>
- * @author Copyright &copy; 2000 The Apache Software Foundation.
- * @version 1.0 CVS $Revision$ $Date$
- */
-public abstract class SAXParserFactory {
-
-    /** Wether the SAXParser to be generated must support namespaces. */
-    private boolean namespaces=false;
-    /** Wether the SAXParser to be generated must support validataion. */
-    private boolean validation=false;
-    /** The system property to check for the SAXParserFactory class name. */
-    private static String property="javax.xml.parsers.SAXParserFactory";
-    /** The default SAXParserFactory implementation class name. */
-    private static String factory="org.apache.xerces.jaxp.SAXParserFactoryImpl";
-
-    /**
-     * Implementors of this abstract class <b>must</b> provide their own
-     * public no-argument constructor in order for the static
-     * <code>newInstance()</code> method to work correctly.
-     * <br>
-     * Application programmers should be able to instantiate an implementation
-     * of this abstract class directly if they want to use a specfic
-     * implementation of this API without using the static newInstance method
-     * to obtain the configured or platform default implementation.
-     */
-    protected SAXParserFactory() {
-        super();
-    }
-
-    /**
-     * Returns a new instance of a <code>SAXParserFactory</code>.
-     * <br>
-     * The implementation of the SAX-ParserFactory returned depends on the
-     * setting of the <code>javax.xml.parsers.SAXParserFactory</code>
-     * system property or, if the property is not set, a platform specific
-     * default.
-     *
-     * @exception FactoryConfigurationError If the class implementing the
-     *                factory cannot be found or instantiated.
-     *                An <code>Error</code> is thrown instead of an exception
-     *                because the application is not expected to handle or
-     *                recover from such events.
-     */
-    public static SAXParserFactory newInstance() {
-
-        // Retrieve the javax.xml.parsers.SAXParserFactory system property
-        String n=factory;
-        try {
-            n=System.getProperty(property, factory);
-        } catch (SecurityException e) {
-        	// In applets System.getProperty throws a SecurityException.
-        	// Thanks to Aaron Buchanan <abuchanan@inovacorp.com> and to
-        	// James Duncan Davidson <james.davidson@eng.sun.com> for this
-        	n=factory;
-        }
-
-        try {
-            // Attempt to load, instantiate and return the factory class
-            return (SAXParserFactory)Class.forName(n).newInstance();
-
-        } catch (ClassNotFoundException e) {
-            // The factory class was not found
-            throw new FactoryConfigurationError("Cannot load class "+
-                "SAXParserFactory class \""+n+"\"");
-
-        } catch (InstantiationException e) {
-            // The factory class wasn't instantiated
-            throw new FactoryConfigurationError("Cannot instantiate the "+
-                "specified SAXParserFactory class \""+n+"\"");
-
-        } catch (IllegalAccessException e) {
-            // The factory class couldn't have been accessed
-            throw new FactoryConfigurationError("Cannot access the specified "+
-                "SAXParserFactory class \""+n+"\"");
-
-        } catch (ClassCastException e) {
-            // The factory class was not a SAXParserFactory
-            throw new FactoryConfigurationError("The specified class \""+n+
-                "\" is not instance of \"javax.xml.parsers.SAXParserFactory\"");
-        }
-    }
-
-    /**
-     * Returns a new configured instance of type <code>SAXParser</code>.
-     *
-     * @exception ParserConfigurationException If the <code>SAXParser</code>
-     *                instance cannot be created with the requested
-     *                configuration.
-     * @exception SAXException If the initialization of the underlying parser
-     *                fails.
-     */
-    public abstract SAXParser newSAXParser()
-    throws ParserConfigurationException, SAXException;
-
-    /**
-     * Configuration method that specifies whether the parsers created by this
-     * factory are required to provide XML namespace support or not.
-     * <br>
-     * <b>NOTE:</b> if a parser cannot be created by this factory that
-     *     satisfies the requested namespace awareness value, a
-     *     <code>ParserConfigurationException</code> will be thrown when the
-     *     program attempts to aquire the parser calling the
-     *     <code>newSaxParser()</code> method.
-     */
-    public void setNamespaceAware(boolean aware) {
-        this.namespaces=aware;
-    }
-
-    /**
-     * Configuration method whether specifies if the parsers created by this
-     * factory are required to validate the XML documents that they parse.
-     * <br>
-     * <b>NOTE:</b> if a parser cannot be created by this factory that
-     *     satisfies the requested validation capacity, a
-     *     <code>ParserConfigurationException</code> will be thrown when
-     *     the application attempts to aquire the parser via the
-     *     <code>newSaxParser()</code> method.
-     */
-    public void setValidating(boolean validating) {
-        this.validation=validating;
-    }
-
-    /**
-     * Indicates if this <code>SAXParserFactory</code> is configured to
-     * produce parsers that are namespace aware or not.
-     */
-    public boolean isNamespaceAware() {
-        return(this.namespaces);
-    }
-
-    /**
-     * Indicates if this <code>SAXParserFactory</code> is configured to
-     * produce parsers that validate XML documents as they are parsed.
-     */
-    public boolean isValidating() {
-        return(this.validation);
-    }
-}
diff --git a/src/javax/xml/parsers/package.html b/src/javax/xml/parsers/package.html
deleted file mode 100644
index 084f4d8..0000000
--- a/src/javax/xml/parsers/package.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!-- CVS $Revision$ $Date$ -->
-<html>
- <body>
-  This package provides a Plugability mechanism to allow a compliant SAX or
-  DOM parser to be used indipendently by an application.
-
-  <dl>
-   <dt><b>Version: </b><dd>1.0 CVS $Revision$ $Date$</dd>
-   <dt><b>Author: </b>
-     <dd><a href="pier@betaversion.org">Pierpaolo Fumagalli</a></dd>
-   <dt><b>Copyright:</b>
-     <dd>Copyright &copy; 2000 The Apache Software Foundation.</dd>
-  </dl>
-
-  <b>ATTENTION:</b>THIS IMPLEMENTATION OF THE "JAVAX.XML.PARSER" CLASSES
-  IS NOT THE OFFICIAL REFERENCE IMPLEMENTATION OF THE JAVA SPECIFICATION
-  REQUEST 5 FOUND AT
-  <a href="http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html">
-  http://java.sun.com/aboutJava/communityprocess/jsr/jsr_005_xml.html
-  </a>
-  <br>
-  THIS IMPLEMENTATION IS CONFORMANT TO THE "JAVA API FOR XML PARSING"
-  SPECIFICATION VERSION 1.0 PUBLIC RELEASE 1 BY JAMES DUNCAN DAVIDSON
-  PUBLISHED BY SUN MICROSYSTEMS ON FEB. 18, 2000 AND FOUND AT
-  <a href="http://java.sun.com/xml">http://java.sun.com/xml</a>
-  <br>
-  <br>
-  <b>THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
-  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- </body>
-</html>
diff --git a/src/org/Makefile b/src/org/Makefile
deleted file mode 100644
index cdd925e..0000000
--- a/src/org/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Makefile for directory ./org
-
-TARGETS =
-
-DIRS = apache w3c xml
-
-TOP = ../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/Makefile b/src/org/apache/Makefile
deleted file mode 100644
index d2505ba..0000000
--- a/src/org/apache/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Makefile for directory ./org/apache
-
-TARGETS =
-
-DIRS = xerces xml html wml
-
-TOP = ../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/html/Makefile b/src/org/apache/html/Makefile
deleted file mode 100644
index c2b58c8..0000000
--- a/src/org/apache/html/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Makefile for directory ./org/apache/html
-
-TARGETS=
-
-DIRS = dom
-
-TOP = ../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/html/dom/HTMLAnchorElementImpl.java b/src/org/apache/html/dom/HTMLAnchorElementImpl.java
deleted file mode 100755
index a915258..0000000
--- a/src/org/apache/html/dom/HTMLAnchorElementImpl.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLAnchorElement
- * @see ElementImpl
- */
-public final class HTMLAnchorElementImpl
-    extends HTMLElementImpl
-    implements HTMLAnchorElement
-{
-    
-    
-    public String getAccessKey()
-    {
-        String    accessKey;
-        
-        // Make sure that the access key is a single character.
-        accessKey = getAttribute( "accesskey" );
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        return accessKey;
-    }
-    
-    
-    public void setAccessKey( String accessKey )
-    {
-        // Make sure that the access key is a single character.
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        setAttribute( "accesskey", accessKey );
-    }
-
-    
-    public String getCharset()
-    {
-        return getAttribute( "charset" );
-    }
-    
-    
-    public void setCharset( String charset )
-    {
-        setAttribute( "charset", charset );
-    }
-    
-    
-    public String getCoords()
-    {
-        return getAttribute( "coords" );
-    }
-    
-    
-    public void setCoords( String coords )
-    {
-        setAttribute( "coords", coords );
-    }
-  
-  
-    public String getHref()
-    {
-        return getAttribute( "href" );
-    }
-    
-    
-    public void setHref( String href )
-    {
-        setAttribute( "href", href );
-    }
-    
-    
-    public String getHreflang()
-    {
-        return getAttribute( "hreflang" );
-    }
-    
-    
-    public void setHreflang( String hreflang )
-    {
-        setAttribute( "hreflang", hreflang );
-    }
-  
-  
-    public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-    
-    
-    public String getRel()
-    {
-        return getAttribute( "rel" );
-    }
-    
-    
-    public void setRel( String rel )
-    {
-        setAttribute( "rel", rel );
-    }
-
-    
-    public String getRev()
-    {
-        return getAttribute( "rev" );
-    }
-    
-    
-    public void setRev( String rev )
-    {
-        setAttribute( "rev", rev );
-    }
-
-
-    public String getShape()
-    {
-        return capitalize( getAttribute( "shape" ) );
-    }
-    
-    
-    public void setShape( String shape )
-    {
-        setAttribute( "shape", shape );
-    }
-  
-
-    public int getTabIndex()
-    {
-        return this.getInteger( getAttribute( "tabindex" ) );
-    }
-    
-    
-    public void setTabIndex( int tabIndex )
-    {
-        setAttribute( "tabindex", String.valueOf( tabIndex ) );
-    }
-
-  
-    public String getTarget()
-    {
-        return getAttribute( "target" );
-    }
-    
-    
-    public void setTarget( String target )
-    {
-        setAttribute( "target", target );
-    }
-    
-    
-    public String getType()
-    {
-        return getAttribute( "type" );
-    }
-    
-    
-    public void setType( String type )
-    {
-        setAttribute( "type", type );
-    }
-
-    
-    public void blur()
-    {
-        // No scripting in server-side DOM. This method is moot.
-    }
-    
-    public void focus()
-    {
-        // No scripting in server-side DOM. This method is moot.
-    }
-  
-  
-      /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLAnchorElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLAppletElementImpl.java b/src/org/apache/html/dom/HTMLAppletElementImpl.java
deleted file mode 100755
index 4efb26e..0000000
--- a/src/org/apache/html/dom/HTMLAppletElementImpl.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLAppletElement
- * @see HTMLElementImpl
- */
-public final class HTMLAppletElementImpl
-    extends HTMLElementImpl
-    implements HTMLAppletElement
-{
-
-    
-    public String getAlign()
-    {
-        return getAttribute( "align" );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-  
-  
-    public String getAlt()
-    {
-        return getAttribute( "alt" );
-    }
-    
-    
-    public void setAlt( String alt )
-    {
-        setAttribute( "alt", alt );
-    }
-
-    
-    public String getArchive()
-    {
-        return getAttribute( "archive" );
-    }
-    
-    
-    public void setArchive( String archive )
-    {
-        setAttribute( "archive", archive );
-    }
-
-
-    public String getCode()
-    {
-        return getAttribute( "code" );
-    }
-    
-    
-    public void setCode( String code )
-    {
-        setAttribute( "code", code );
-    }
-
-
-    public String getCodeBase()
-    {
-        return getAttribute( "codebase" );
-    }
-    
-    
-    public void setCodeBase( String codeBase )
-    {
-        setAttribute( "codebase", codeBase );
-    }
-
-
-    public String getHeight()
-    {
-        return getAttribute( "height" );
-    }
-    
-    
-    public void setHeight( String height )
-    {
-        setAttribute( "height", height );
-    }
-
-
-    public String getHspace()
-    {
-        return getAttribute( "height" );
-    }
-    
-    
-    public void setHspace( String height )
-    {
-        setAttribute( "height", height );
-    }
-
-
-    public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-
-
-    public String getObject()
-    {
-        return getAttribute( "object" );
-    }
-    
-    
-    public void setObject( String object )
-    {
-        setAttribute( "object", object );
-    }
-
-
-    public String getVspace()
-    {
-        return getAttribute( "vspace" );
-    }
-    
-    
-    public void setVspace( String vspace )
-    {
-        setAttribute( "vspace", vspace );
-    }
-
-
-    public String getWidth()
-    {
-        return getAttribute( "width" );
-    }
-    
-    
-    public void setWidth( String width )
-    {
-        setAttribute( "width", width );
-    }
-
-
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLAppletElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-    
-}
-
diff --git a/src/org/apache/html/dom/HTMLAreaElementImpl.java b/src/org/apache/html/dom/HTMLAreaElementImpl.java
deleted file mode 100755
index a8e5f4b..0000000
--- a/src/org/apache/html/dom/HTMLAreaElementImpl.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLAreaElement
- * @see ElementImpl
- */
-public final class HTMLAreaElementImpl
-    extends HTMLElementImpl
-    implements HTMLAreaElement
-{
-    
-    
-    public String getAccessKey()
-    {
-        String    accessKey;
-        
-        // Make sure that the access key is a single character.
-        accessKey = getAttribute( "accesskey" );
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        return accessKey;
-    }
-    
-    
-    public void setAccessKey( String accessKey )
-    {
-        // Make sure that the access key is a single character.
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        setAttribute( "accesskey", accessKey );
-    }
-
-    
-    public String getAlt()
-    {
-        return getAttribute( "alt" );
-    }
-    
-    
-    public void setAlt( String alt )
-    {
-        setAttribute( "alt", alt );
-    }
-    
-    public String getCoords()
-    {
-        return getAttribute( "coords" );
-    }
-    
-    
-    public void setCoords( String coords )
-    {
-        setAttribute( "coords", coords );
-    }
-  
-  
-    public String getHref()
-    {
-        return getAttribute( "href" );
-    }
-    
-    
-    public void setHref( String href )
-    {
-        setAttribute( "href", href );
-    }
-
-    
-    public boolean getNoHref()
-    {
-        return getBinary( "href" );
-    }
-    
-    
-    public void setNoHref( boolean noHref )
-    {
-        setAttribute( "nohref", noHref );
-    }
-    
-    
-    public String getShape()
-    {
-        return capitalize( getAttribute( "shape" ) );
-    }
-    
-    
-    public void setShape( String shape )
-    {
-        setAttribute( "shape", shape );
-    }
-
-    
-    public int getTabIndex()
-    {
-        return getInteger( getAttribute( "tabindex" ) );
-    }
-    
-    
-    public void setTabIndex( int tabIndex )
-    {
-        setAttribute( "tabindex", String.valueOf( tabIndex ) );
-    }
-
-    
-    public String getTarget()
-    {
-        return getAttribute( "target" );
-    }
-    
-    
-    public void setTarget( String target )
-    {
-        setAttribute( "target", target );
-    }
-    
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLAreaElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-    
-}
-
diff --git a/src/org/apache/html/dom/HTMLBRElementImpl.java b/src/org/apache/html/dom/HTMLBRElementImpl.java
deleted file mode 100755
index ee8055c..0000000
--- a/src/org/apache/html/dom/HTMLBRElementImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLBRElement
- * @see ElementImpl
- */
-public final class HTMLBRElementImpl
-    extends HTMLElementImpl
-    implements HTMLBRElement
-{
-
-    
-    public String getClear()
-    {
-        return capitalize( getAttribute( "clear" ) );
-    }
-    
-    
-    public void setClear( String clear )
-    {
-        setAttribute( "clear", clear );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLBRElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLBaseElementImpl.java b/src/org/apache/html/dom/HTMLBaseElementImpl.java
deleted file mode 100755
index 8201875..0000000
--- a/src/org/apache/html/dom/HTMLBaseElementImpl.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLBaseElement
- * @see ElementImpl
- */
-public final class HTMLBaseElementImpl
-    extends HTMLElementImpl
-    implements HTMLBaseElement
-{
-
-    
-    public String getHref()
-    {
-        return getAttribute( "href" );
-    }
-    
-    
-    public void setHref( String href )
-    {
-        setAttribute( "href", href );
-    }
-    
-    public String getTarget()
-    {
-        return getAttribute( "target" );
-    }
-    
-    
-    public void setTarget( String target )
-    {
-        setAttribute( "target", target );
-    }
-
-
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLBaseElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLBaseFontElementImpl.java b/src/org/apache/html/dom/HTMLBaseFontElementImpl.java
deleted file mode 100755
index b0847aa..0000000
--- a/src/org/apache/html/dom/HTMLBaseFontElementImpl.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLBaseFontElement
- * @see ElementImpl
- */
-public final class HTMLBaseFontElementImpl
-    extends HTMLElementImpl
-    implements HTMLBaseFontElement
-{
-    
-    
-    public String getColor()
-    {
-        return capitalize( getAttribute( "color" ) );
-    }
-    
-    
-    public void setColor( String color )
-    {
-        setAttribute( "color", color );
-    }
-    
-    
-    public String getFace()
-    {
-        return capitalize( getAttribute( "face" ) );
-    }
-    
-    
-    public void setFace( String face )
-    {
-        setAttribute( "face", face );
-    }
-    
-    
-    public String getSize()
-    {
-        return getAttribute( "size" );
-    }
-    
-    
-    public void setSize( String size )
-    {
-        setAttribute( "size", size );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLBaseFontElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLBodyElementImpl.java b/src/org/apache/html/dom/HTMLBodyElementImpl.java
deleted file mode 100755
index a85ce5d..0000000
--- a/src/org/apache/html/dom/HTMLBodyElementImpl.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLBodyElement
- * @see ElementImpl
- */
-public final class HTMLBodyElementImpl
-    extends HTMLElementImpl
-    implements HTMLBodyElement
-{
-    
-    public String getALink()
-    {
-        return getAttribute( "alink" );
-    }
-
-    
-    public void setALink(String aLink)
-    {
-        setAttribute( "alink", aLink );
-    }
-    
-  
-    public String getBackground()
-    {
-        return getAttribute( "background" );
-    }
-    
-  
-    public void setBackground( String background )
-    {
-        setAttribute( "background", background );
-    }
-    
-  
-    public String getBgColor()
-    {
-        return getAttribute( "bgcolor" );
-    }
-    
-    
-    public void setBgColor(String bgColor)
-    {
-        setAttribute( "bgcolor", bgColor );
-    }
-    
-  
-    public String getLink()
-    {
-        return getAttribute( "link" );
-    }
-  
-    
-    public void setLink(String link)
-    {
-        setAttribute( "link", link );
-    }
-    
-  
-    public String getText()
-    {
-        return getAttribute( "text" );
-    }
-    
-  
-    public void setText(String text)
-    {
-        setAttribute( "text", text );
-    }
-    
-  
-    public String getVLink()
-    {
-        return getAttribute( "vlink" );
-    }
-  
-    
-    public void  setVLink(String vLink)
-    {
-        setAttribute( "vlink", vLink );
-    }
-  
-    
-      /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLBodyElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLBuilder.java b/src/org/apache/html/dom/HTMLBuilder.java
deleted file mode 100755
index 6985758..0000000
--- a/src/org/apache/html/dom/HTMLBuilder.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import java.util.Vector;
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-import org.xml.sax.*;
-import org.apache.xerces.dom.TextImpl;
-import org.apache.xerces.dom.ElementImpl;
-import org.apache.xerces.dom.ProcessingInstructionImpl;
-
-
-/**
- * This is a SAX document handler that is used to build an HTML document.
- * It can build a document from any SAX parser, but is specifically tuned
- * for working with the OpenXML HTML parser.
- * 
- * 
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@openxml.org">Assaf Arkin</a>
- */
-public class HTMLBuilder
-    implements DocumentHandler
-{
-
-
-    /**
-     * The document that is being built.
-     */
-    protected HTMLDocumentImpl    _document;
-    
-    
-    /**
-     * The current node in the document into which elements, text and
-     * other nodes will be inserted. This starts as the document iself
-     * and reflects each element that is currently being parsed.
-     */
-    protected ElementImpl        _current;
-    
-    /**
-     * A reference to the current locator, this is generally the parser
-     * itself. The locator is used to locate errors and identify the
-     * source locations of elements.
-     */
-    private Locator         _locator;
-
-
-    /**
-     * Applies only to whitespace appearing between element tags in element content,
-     * as per the SAX definition, and true by default.
-     */
-    private boolean         _ignoreWhitespace = true;
-
-
-    /**
-     * Indicates whether finished building a document. If so, can start building
-     * another document. Must be initially true to get the first document processed.
-     */
-    private boolean         _done = true;
-
-
-    /**    
-     * The document is only created the same time as the document element, however, certain
-     * nodes may precede the document element (comment and PI), and they are accumulated
-     * in this vector.
-     */
-    protected Vector         _preRootNodes;
-
-    
-    public void startDocument()
-        throws SAXException
-    {
-        if ( ! _done )
-	    throw new SAXException( "HTM001 State error: startDocument fired twice on one builder." );
-	_document = null;
-	_done = false;
-    }
-
-
-    public void endDocument()
-        throws SAXException
-    {
-        if ( _document == null )
-            throw new SAXException( "HTM002 State error: document never started or missing document element." );
-	if ( _current != null )
-	    throw new SAXException( "HTM003 State error: document ended before end of document element." );
-        _current = null;
-	_done = true;
-    }
-
-
-    public synchronized void startElement( String tagName, AttributeList attrList )
-        throws SAXException
-    {
-        ElementImpl elem;
-        int         i;
-        
-	if ( tagName == null )
-	    throw new SAXException( "HTM004 Argument 'tagName' is null." );
-
-	// If this is the root element, this is the time to create a new document,
-	// because only know we know the document element name and namespace URI.
-	if ( _document == null )
-	{
-	    // No need to create the element explicitly.
-	    _document = new HTMLDocumentImpl();
-	    elem = (ElementImpl) _document.getDocumentElement();
-	    _current = elem;
-	    if ( _current == null )
-		throw new SAXException( "HTM005 State error: Document.getDocumentElement returns null." );
-
-	    // Insert nodes (comment and PI) that appear before the root element.
-	    if ( _preRootNodes != null )
-	    {
-		for ( i = _preRootNodes.size() ; i-- > 0 ; )
-		    _document.insertBefore( (Node) _preRootNodes.elementAt( i ), elem );
-		_preRootNodes = null;
-	    }
-	     
-	}
-	else
-	{
-	    // This is a state error, indicates that document has been parsed in full,
-	    // or that there are two root elements.
-	    if ( _current == null )
-		throw new SAXException( "HTM006 State error: startElement called after end of document element." );
-	    elem = (ElementImpl) _document.createElement( tagName );
-	    _current.appendChild( elem );
-	    _current = elem;
-	}
-
-	// Add the attributes (specified and not-specified) to this element.
-        if ( attrList != null )
-        {
-            for ( i = 0 ; i < attrList.getLength() ; ++ i )
-                elem.setAttribute( attrList.getName( i ), attrList.getValue( i ) );
-        }
-    }
-
-    
-    public void endElement( String tagName )
-        throws SAXException
-    {
-
-        if ( _current == null )
-            throw new SAXException( "HTM007 State error: endElement called with no current node." );
-	if ( ! _current.getNodeName().equals( tagName ) )
-	    throw new SAXException( "HTM008 State error: mismatch in closing tag name " + tagName + "\n" + tagName);
-
-	// Move up to the parent element. When you reach the top (closing the root element).
-	// the parent is document and current is null.
-	if ( _current.getParentNode() == _current.getOwnerDocument() )
-	    _current = null;
-	else
-	    _current = (ElementImpl) _current.getParentNode();
-    }
-
-
-    public void characters( String text )
-        throws SAXException
-    {
-	if ( _current == null )
-            throw new SAXException( "HTM009 State error: character data found outside of root element." );
-	_current.appendChild( new TextImpl( _document, text ) );
-    }
-
-    
-    public void characters( char[] text, int start, int length )
-        throws SAXException
-    {
-	if ( _current == null )
-            throw new SAXException( "HTM010 State error: character data found outside of root element." );
-	_current.appendChild( new TextImpl( _document, new String( text, start, length ) ) );
-    }
-    
-    
-    public void ignorableWhitespace( char[] text, int start, int length )
-        throws SAXException
-    {
-        Node    node;
-        
-        if ( ! _ignoreWhitespace )
-	    _current.appendChild( new TextImpl( _document, new String( text, start, length ) ) );
-     }
-    
-    
-    public void processingInstruction( String target, String instruction )
-        throws SAXException
-    {
-        Node    node;
-        
-	// Processing instruction may appear before the document element (in fact, before the
-	// document has been created, or after the document element has been closed.
-        if ( _current == null && _document == null )
-	{
-	    if ( _preRootNodes == null )
-		_preRootNodes = new Vector();
-	    _preRootNodes.addElement( new ProcessingInstructionImpl( null, target, instruction ) );
-	}
-	else
-        if ( _current == null && _document != null )
-	    _document.appendChild( new ProcessingInstructionImpl( _document, target, instruction ) );
-	else
-	    _current.appendChild( new ProcessingInstructionImpl( _document, target, instruction ) );
-    }
-    
-    
-    public HTMLDocument getHTMLDocument()
-    {
-        return (HTMLDocument) _document;
-    }
-
-    
-    public void setDocumentLocator( Locator locator )
-    {
-        _locator = locator;
-    }
-
-
-}
diff --git a/src/org/apache/html/dom/HTMLButtonElementImpl.java b/src/org/apache/html/dom/HTMLButtonElementImpl.java
deleted file mode 100755
index 7950b8f..0000000
--- a/src/org/apache/html/dom/HTMLButtonElementImpl.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLButtonElement
- * @see ElementImpl
- */
-public final class HTMLButtonElementImpl
-    extends HTMLElementImpl
-    implements HTMLButtonElement, HTMLFormControl
-{
-
-    
-      public String getAccessKey()
-    {
-        String    accessKey;
-        
-        // Make sure that the access key is a single character.
-        accessKey = getAttribute( "accesskey" );
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        return accessKey;
-    }
-    
-    
-    public void setAccessKey( String accessKey )
-    {
-        // Make sure that the access key is a single character.
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        setAttribute( "accesskey", accessKey );
-    }
-
-    
-    public boolean getDisabled()
-    {
-        return getBinary( "disabled" );
-    }
-    
-    
-    public void setDisabled( boolean disabled )
-    {
-        setAttribute( "disabled", disabled );
-    }
-
-
-    public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-
-    
-    public int getTabIndex()
-    {
-        try
-        {
-            return Integer.parseInt( getAttribute( "tabindex" ) );
-        }
-        catch ( NumberFormatException except )
-        {
-            return 0;
-        }
-    }
-    
-    
-    public void setTabIndex( int tabIndex )
-    {
-        setAttribute( "tabindex", String.valueOf( tabIndex ) );
-    }
-
-    
-    public String getType()
-    {
-        return capitalize( getAttribute( "type" ) );
-    }
-
-    
-      public String getValue()
-    {
-        return getAttribute( "value" );
-    }
-    
-    
-    public void setValue( String value )
-    {
-        setAttribute( "value", value );
-    }
-    
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLButtonElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-  
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLCollectionImpl.java b/src/org/apache/html/dom/HTMLCollectionImpl.java
deleted file mode 100755
index 8cef36d..0000000
--- a/src/org/apache/html/dom/HTMLCollectionImpl.java
+++ /dev/null
@@ -1,560 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * Implements {@link org.w3c.dom.html.HTMLCollection} to traverse any named
- * elements on a {@link org.w3c.dom.html.HTMLDocument}. The elements type to
- * look for is identified in the constructor by code. This collection is not
- * optimized for traversing large trees.
- * <p>
- * The collection has to meet two requirements: it has to be live, and it has
- * to traverse depth first and always return results in that order. As such,
- * using an object container (such as {@link java.util.Vector}) is expensive on
- * insert/remove operations. Instead, the collection has been implemented using
- * three traversing functions. As a result, operations on large documents will
- * result in traversal of the entire document tree and consume a considerable
- * amount of time.
- * <p>
- * Note that synchronization on the traversed document cannot be achieved.
- * The document itself cannot be locked, and locking each traversed node is
- * likely to lead to a dead lock condition. Therefore, there is a chance of the
- * document being changed as results are fetched; in all likelihood, the results
- * might be out dated, but not erroneous.
- * 
- * 
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLCollection
- */
-final class HTMLCollectionImpl
-    implements HTMLCollection
-{
-    
-
-    /**
-     * Request collection of all anchors in document: &lt;A&gt; elements that
-     * have a <code>name</code> attribute.
-     */
-    static final short        ANCHOR = 1;
-    
-    
-    /**
-     * Request collection of all forms in document: &lt;FORM&gt; elements.
-     */
-    static final short        FORM = 2;
-    
-    
-    /**
-     * Request collection of all images in document: &lt;IMAGE&gt; elements.
-     */
-    static final short        IMAGE = 3;
-    
-    
-    /**
-     * Request collection of all Applets in document: &lt;APPLET&gt; and
-     * &lt;OBJECT&gt; elements (&lt;OBJECT&gt; must contain an Applet).
-     */
-    static final short        APPLET = 4;
-    
-    
-    /**
-     * Request collection of all links in document: &lt;A&gt; and &lt;AREA&gt;
-     * elements (must have a <code>href</code> attribute).
-     */
-    static final short        LINK = 5;
-    
-    
-    /**
-     * Request collection of all options in selection: &lt;OPTION&gt; elments in
-     * &lt;SELECT&gt; or &lt;OPTGROUP&gt;.
-     */
-    static final short        OPTION = 6;
-    
-    
-    /**
-     * Request collection of all rows in table: &lt;TR&gt; elements in table or
-     * table section.
-     */
-    static final short        ROW = 7;
-
-    
-    /**
-     * Request collection of all form elements: &lt;INPUT&gt;, &lt;BUTTON&gt;,
-     * &lt;SELECT&gt;, &lt;TEXT&gt; and &lt;TEXTAREA&gt; elements inside form
-     * &lt;FORM&gt;.
-     */
-    static final short        ELEMENT = 8;
-    
-    
-    /**
-     * Request collection of all areas in map: &lt;AREA&gt; element in &lt;MAP&gt;
-     * (non recursive).
-     */
-    static final short        AREA = -1;
-    
-
-    /**
-     * Request collection of all table bodies in table: &lt;TBODY&gt; element in
-     * table &lt;TABLE&gt; (non recursive).
-     */
-    static final short        TBODY = -2;
-
-    
-    /**
-     * Request collection of all cells in row: &lt;TD&gt; elements in &lt;TR&gt;
-     * (non recursive).
-     */
-    static final short        CELL = -3;
-
-    
-    /**
-     * Indicates what this collection is looking for. Holds one of the enumerated
-     * values and used by {@link #collectionMatch}. Set by the constructor and
-     * determine the collection's use for its life time.
-     */
-    private short            _lookingFor;
-    
-    
-    /**
-     * This is the top level element underneath which the collection exists.
-     */
-    private Element            _topLevel;
-
-
-    /**
-     * Construct a new collection that retrieves element of the specific type
-     * (<code>lookingFor</code>) from the specific document portion
-     * (<code>topLevel</code>).
-     * 
-     * @param topLevel The element underneath which the collection exists
-     * @param lookingFor Code indicating what elements to look for
-     */
-    HTMLCollectionImpl( HTMLElement topLevel, short lookingFor )
-    {
-        if ( topLevel == null )
-            throw new NullPointerException( "HTM011 Argument 'topLevel' is null." );
-        _topLevel = topLevel;
-       _lookingFor = lookingFor;
-    }
-  
-  
-    /**
-     * Returns the length of the collection. This method might traverse the
-     * entire document tree.
-     * 
-     * @return Length of the collection
-     */
-    public final int getLength()
-    {
-        // Call recursive function on top-level element.
-        return getLength( _topLevel );
-    }
-
-
-    /**
-     * Retrieves the indexed node from the collection. Nodes are numbered in
-     * tree order - depth-first traversal order. This method might traverse
-     * the entire document tree.
-     * 
-     * @param index The index of the node to return
-     * @return The specified node or null if no such node found
-     */
-    public final Node item( int index )
-    {
-        if ( index < 0 )
-            throw new IllegalArgumentException( "HTM012 Argument 'index' is negative." );
-        // Call recursive function on top-level element.
-        return item( _topLevel, new CollectionIndex( index ) );
-    }
-    
-    
-    /**
-     * Retrieves the named node from the collection. The name is matched case
-     * sensitive against the <TT>id</TT> attribute of each element in the
-     * collection, returning the first match. The tree is traversed in
-     * depth-first order. This method might traverse the entire document tree.
-     * 
-     * @param name The name of the node to return
-     * @return The specified node or null if no such node found
-     */
-    public final Node namedItem( String name )
-    {
-        if ( name == null )
-            throw new NullPointerException( "HTM013 Argument 'name' is null." );
-        // Call recursive function on top-level element.
-        return namedItem( _topLevel, name );
-    }
-    
-    
-    /**
-     * Recursive function returns the number of elements of a particular type
-     * that exist under the top level element. This is a recursive function
-     * and the top level element is passed along.
-     * 
-     * @param topLevel Top level element from which to scan
-     * @return Number of elements
-     */
-    private int getLength( Element topLevel )
-    {
-        int        length;
-        Node    node;
-    
-        synchronized ( topLevel )
-        {
-            // Always count from zero and traverse all the childs of the
-            // current element in the order they appear.
-            length = 0;
-            node = topLevel.getFirstChild();
-            while ( node != null )
-            {
-                // If a particular node is an element (could be HTML or XML),
-		// do two things: if it's the one we're looking for, count
-		// another matched element; at any rate, traverse it's
-		// children as well.
-                if ( node instanceof Element )
-                {
-                    if ( collectionMatch( (Element) node, null ) )
-                        ++ length;
-                    else if ( recurse() )
-                        length += getLength( (Element) node );
-                }
-                node = node.getNextSibling(); 
-            }
-        }
-        return length;
-    }
-    
-        
-    /**
-     * Recursive function returns the numbered element of a particular type
-     * that exist under the top level element. This is a recursive function
-     * and the top level element is passed along.
-     * <p>
-     * Note that this function must call itself with an index and get back both
-     * the element (if one was found) and the new index which is decremeneted
-     * for any like element found. Since integers are only passed by value,
-     * this function makes use of a separate class ({@link CollectionIndex})
-     * to hold that index.
-     * 
-     * @param topLevel Top level element from which to scan
-     * @param index The index of the item to retreive
-     * @return Number of elements
-     * @see CollectionIndex
-     */
-    private Node item( Element topLevel, CollectionIndex index )
-    {
-        Node    node;
-        Node    result;
-
-        synchronized ( topLevel )
-        {
-            // Traverse all the childs of the current element in the order
-	    // they appear. Count from the index backwards until you reach
-	    // matching element with an index of zero. Return that element.
-            node = topLevel.getFirstChild();
-            while ( node != null )
-            {
-                // If a particular node is an element (could be HTML or XML),
-		// do two things: if it's the one we're looking for, decrease
-		// the index and if zero, return this node; at any rate,
-		// traverse it's children as well.
-                if ( node instanceof Element )
-                {
-                    if ( collectionMatch( (Element) node, null ) )
-                    {
-                        if ( index.isZero() )
-                            return node;
-                        index.decrement();
-                    } else if ( recurse() )
-                    {
-                        result = item( (Element) node, index );
-                        if ( result != null )
-                            return result;
-                    }
-                }
-                node = node.getNextSibling(); 
-            }
-        }
-        return null;
-    }
-    
-    
-    /**
-     * Recursive function returns an element of a particular type with the
-     * specified name (<TT>id</TT> attribute).
-     * 
-     * @param topLevel Top level element from which to scan
-     * @param name The named element to look for
-     * @return The first named element found
-     */
-    private  Node namedItem( Element topLevel, String name )
-    {
-        Node    node;
-        Node    result;
-
-        synchronized ( topLevel )
-        {
-            // Traverse all the childs of the current element in the order
-	    // they appear.
-            node = topLevel.getFirstChild();
-            while ( node != null )
-            {
-                // If a particular node is an element (could be HTML or XML),
-                // do two things: if it's the one we're looking for, and the
-		// name (id attribute) attribute is the one we're looking for,
-		// return this element; otherwise, traverse it's children.
-                if ( node instanceof Element )
-                {
-                    if ( collectionMatch( (Element) node, name ) )
-                        return node;
-                    else if ( recurse() )
-                    {
-                        result = namedItem( (Element) node, name );
-                        if ( result != null )
-                            return result;
-                    }
-                }
-                node = node.getNextSibling(); 
-            }
-            return node;
-        }
-    }
-    
-    
-    /**
-     * Returns true if scanning methods should iterate through the collection.
-     * When looking for elements in the document, recursing is needed to traverse
-     * the full document tree. When looking inside a specific element (e.g. for a
-     * cell inside a row), recursing can lead to erroneous results.
-     * 
-     * @return True if methods should recurse to traverse entire tree
-     */
-    protected boolean recurse()
-    {
-        return _lookingFor > 0;
-    }
-    
-
-    /**
-     * Determines if current element matches based on what we're looking for.
-     * The element is passed along with an optional identifier name. If the
-     * element is the one we're looking for, return true. If the name is also
-     * specified, the name must match the <code>id</code> attribute
-     * (match <code>name</code> first for anchors).
-     * 
-     * @param elem The current element
-     * @param name The identifier name or null
-     * @return The element matches what we're looking for
-     */
-    protected boolean collectionMatch( Element elem, String name )
-    {
-        boolean    match;
-        
-        synchronized ( elem )
-        {
-            // Begin with no matching. Depending on what we're looking for,
-            // attempt to match based on the element type. This is the quickest
-            // way to match involving only a cast. Do the expensive string
-            // comparison later on.
-            match = false;
-            switch ( _lookingFor )
-            {
-            case ANCHOR:
-                // Anchor is an <A> element with a 'name' attribute. Otherwise, it's
-                // just a link.
-                match = ( elem instanceof HTMLAnchorElement ) &&
-                        elem.getAttribute( "name" ).length() > 0;
-                break;
-            case FORM:
-                // Any <FORM> element.
-                match = ( elem instanceof HTMLFormElement );
-                break;
-            case IMAGE:
-                // Any <IMG> element. <OBJECT> elements with images are not returned.
-                match = ( elem instanceof HTMLImageElement );
-                break;
-            case APPLET:
-                // Any <APPLET> element, and any <OBJECT> element which represents an
-                // Applet. This is determined by 'codetype' attribute being
-                // 'application/java' or 'classid' attribute starting with 'java:'.
-                match = ( elem instanceof HTMLAppletElement ) ||
-                        ( elem instanceof HTMLObjectElement &&
-                          ( "application/java".equals( elem.getAttribute( "codetype" ) ) ||
-                            elem.getAttribute( "classid" ).startsWith( "java:" ) ) );
-                break;
-            case ELEMENT:
-                // All form elements implement HTMLFormControl for easy identification.
-                match = ( elem instanceof HTMLFormControl );
-                break;
-            case LINK:
-                // Any <A> element, and any <AREA> elements with an 'href' attribute.
-                match = ( ( elem instanceof HTMLAnchorElement ||
-                            elem instanceof HTMLAreaElement ) &&
-                          elem.getAttribute( "href" ).length() > 0 );
-                break;
-            case AREA:
-                // Any <AREA> element.
-                match = ( elem instanceof HTMLAreaElement );
-                break;
-            case OPTION:
-                // Any <OPTION> element.
-                match = ( elem instanceof HTMLOptionElement );
-                break;
-            case ROW:
-                // Any <TR> element.
-                match = ( elem instanceof HTMLTableRowElement );
-                break;
-            case TBODY:
-                // Any <TBODY> element (one of three table section types).
-                match = ( elem instanceof HTMLTableSectionElement &&
-                          elem.getTagName().equals( "tbody" ) );
-                break;
-            case CELL:
-                // Any <TD> element.
-                match = ( elem instanceof HTMLTableCellElement );
-                break;
-            }
-        
-            // If element type was matched and a name was specified, must also match
-            // the name against either the 'id' or the 'name' attribute. The 'name'
-            // attribute is relevant only for <A> elements for backward compatibility.
-            if ( match && name != null )
-            {
-                // If an anchor and 'name' attribute matches, return true. Otherwise,
-                // try 'id' attribute.
-                if ( elem instanceof HTMLAnchorElement &&
-                     name.equals( elem.getAttribute( "name" ) ) )
-                    return true;
-                match = name.equals( elem.getAttribute( "id" ) );
-            }
-        }
-        return match;
-    }
-
-    
-}
-
-
-/**
- * {@link CollectionImpl#item} must traverse down the tree and decrement the
- * index until it matches an element who's index is zero. Since integers are
- * passed by value, this class servers to pass the index into each recursion
- * by reference. It encompasses all the operations that need be performed on
- * the index, although direct access is possible.
- * 
- * @see CollectionImpl#item
- */
-class CollectionIndex
-{
-    
-    
-    /**
-     * Returns the current index.
-     * 
-     * @return Current index
-     */
-    int getIndex()
-    {
-        return _index;
-    }
-    
-    
-    /**
-     * Decrements the index by one.
-     */
-    void decrement()
-    {
-        -- _index;
-    }
-    
-    
-    /**
-     * Returns true if index is zero (or negative).
-     * 
-     * @return True if index is zero
-     */
-    boolean isZero()
-    {
-        return _index <= 0;
-    }
-    
-    
-    /**
-     * Constructs a new index with the specified initial value. The index will
-     * then be decremeneted until it reaches zero.
-     * 
-     * @param index The initial value
-     */
-    CollectionIndex( int index )
-    {
-        _index = index;
-    }
-    
-    
-    /**
-     * Holds the actual value that is passed by reference using this class.
-     */
-    private int        _index;
-    
-
-}
diff --git a/src/org/apache/html/dom/HTMLDListElementImpl.java b/src/org/apache/html/dom/HTMLDListElementImpl.java
deleted file mode 100755
index 4c06243..0000000
--- a/src/org/apache/html/dom/HTMLDListElementImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLDListElement
- * @see ElementImpl
- */
-public final class HTMLDListElementImpl
-    extends HTMLElementImpl
-    implements HTMLDListElement
-{
-    
-    
-    public boolean getCompact()
-    {
-        return getBinary( "compact" );
-    }
-    
-    
-    public void setCompact( boolean compact )
-    {
-        setAttribute( "compact", compact );
-    }
-  
-    
-      /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLDListElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-    
-}
-
diff --git a/src/org/apache/html/dom/HTMLDOMImplementationImpl.java b/src/org/apache/html/dom/HTMLDOMImplementationImpl.java
deleted file mode 100644
index 35183e1..0000000
--- a/src/org/apache/html/dom/HTMLDOMImplementationImpl.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-    
-
-import org.w3c.dom.DOMException;
-import org.w3c.dom.html.*;
-import org.apache.xerces.dom.DOMImplementationImpl;
-
-
-/**
- * Provides number of methods for performing operations that are independent
- * of any particular instance of the document object model. This class is
- * unconstructable, the only way to obtain an instance of a DOM implementation
- * is by calling the static method {@link #getDOMImplementation}.
- * 
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.DOMImplementation
- */
-public class HTMLDOMImplementationImpl
-    extends DOMImplementationImpl
-    implements HTMLDOMImplementation
-{
-
-
-    /**
-     * Holds a reference to the single instance of the DOM implementation.
-     * Only one instance is required since this class is multiple entry.
-     */
-    private static HTMLDOMImplementation _instance = new HTMLDOMImplementationImpl();
-
-
-    /**
-     * Private constructor assures that an object of this class cannot
-     * be created. The only way to obtain an object is by calling {@link
-     * #getDOMImplementation}.
-     */
-    private HTMLDOMImplementationImpl()
-    {
-    }
-
-
-    /**
-     * Create a new HTML document of the specified <TT>TITLE</TT> text.
-     *
-     * @param title The document title text
-     * @return New HTML document
-     */
-    public final HTMLDocument createHTMLDocument( String title )
-        throws DOMException
-    {
-	HTMLDocument doc;
-
-	if ( title == null )
-	    throw new NullPointerException( "HTM014 Argument 'title' is null." );
-	doc = new HTMLDocumentImpl();
-	doc.setTitle( title );
-	return doc;
-    }
-
-
-    /**
-     * Returns an instance of a {@link HTMLDOMImplementation} that can be
-     * used to perform operations that are not specific to a particular
-     * document instance, e.g. to create a new document.
-     *
-     * @return Reference to a valid DOM implementation
-     */
-    public static HTMLDOMImplementation getHTMLDOMImplementation()
-    {
-	return _instance;
-    }
-
-
-}
diff --git a/src/org/apache/html/dom/HTMLDirectoryElementImpl.java b/src/org/apache/html/dom/HTMLDirectoryElementImpl.java
deleted file mode 100755
index 79f1667..0000000
--- a/src/org/apache/html/dom/HTMLDirectoryElementImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLDirectoryElement
- * @see ElementImpl
- */
-public final class HTMLDirectoryElementImpl
-    extends HTMLElementImpl
-    implements HTMLDirectoryElement
-{
-    
-    
-    public boolean getCompact()
-    {
-        return getBinary( "compact" );
-    }
-    
-    
-    public void setCompact( boolean compact )
-    {
-        setAttribute( "compact", compact );
-    }
-  
-
-      /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLDirectoryElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLDivElementImpl.java b/src/org/apache/html/dom/HTMLDivElementImpl.java
deleted file mode 100755
index 7afe0b3..0000000
--- a/src/org/apache/html/dom/HTMLDivElementImpl.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLDivElement
- * @see ElementImpl
- */
-public final class HTMLDivElementImpl
-    extends HTMLElementImpl
-    implements HTMLDivElement
-{
-    
-    
-    public String getAlign()
-    {
-        return capitalize( getAttribute( "align" ) );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-  
-    
-      /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLDivElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-    
-}
diff --git a/src/org/apache/html/dom/HTMLDocumentImpl.java b/src/org/apache/html/dom/HTMLDocumentImpl.java
deleted file mode 100755
index da29634..0000000
--- a/src/org/apache/html/dom/HTMLDocumentImpl.java
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import java.io.*;
-import java.util.*;
-import java.lang.reflect.*;
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-import org.apache.xerces.dom.DocumentImpl;
-import org.apache.xerces.dom.NodeImpl;
-import org.apache.xerces.dom.AttrImpl;
-import org.apache.xerces.dom.DOMExceptionImpl;
-
-
-/**
- * Implements an HTML document. Provides access to the top level element in the
- * document, its body and title.
- * <P>
- * Several methods create new nodes of all basic types (comment, text, element,
- * etc.). These methods create new nodes but do not place them in the document
- * tree. The nodes may be placed in the document tree using {@link
- * org.w3c.dom.Node#appendChild} or {@link org.w3c.dom.Node#insertBefore}, or
- * they may be placed in some other document tree.
- * <P>
- * Note: &lt;FRAMESET&gt; documents are not supported at the moment, neither
- * are direct document writing ({@link #open}, {@link #write}) and HTTP attribute
- * methods ({@link #getURL}, {@link #getCookie}).
- *
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLDocument
- */
-public class HTMLDocumentImpl
-    extends DocumentImpl
-    implements HTMLDocument
-{
-
-
-    /**
-     * Holds {@link HTMLCollectionImpl} object with live collection of all
-     * anchors in document. This reference is on demand only once.
-     */
-    private HTMLCollectionImpl    _anchors;
-
-
-    /**
-     * Holds {@link HTMLCollectionImpl} object with live collection of all
-     * forms in document. This reference is on demand only once.
-     */
-    private HTMLCollectionImpl    _forms;
-
-
-    /**
-     * Holds {@link HTMLCollectionImpl} object with live collection of all
-     * images in document. This reference is on demand only once.
-     */
-    private HTMLCollectionImpl    _images;
-
-
-    /**
-     * Holds {@link HTMLCollectionImpl} object with live collection of all
-     * links in document. This reference is on demand only once.
-     */
-    private HTMLCollectionImpl    _links;
-
-
-    /**
-     * Holds {@link HTMLCollectionImpl} object with live collection of all
-     * applets in document. This reference is on demand only once.
-     */
-    private HTMLCollectionImpl    _applets;
-
-
-    /**
-     * Holds string writer used by direct manipulation operation ({@link #open}.
-     * {@link #write}, etc) to write new contents into the document and parse
-     * that text into a document tree.
-     */
-    private StringWriter        _writer;
-
-
-    /**
-     * Holds names and classes of HTML element types. When an element with a
-     * particular tag name is created, the matching {@link java.lang.Class}
-     * is used to create the element object. For example, &lt;A&gt; matches
-     * {@link HTMLAnchorElementImpl}. This static table is shared across all
-     * HTML documents.
-     *
-     * @see #createElement
-     */
-    private static Hashtable        _elementTypesHTML;
-
-
-    /**
-     * Signature used to locate constructor of HTML element classes. This
-     * static array is shared across all HTML documents.
-     *
-     * @see #createElement
-     */
-    private static final Class[]    _elemClassSigHTML =
-                new Class[] { HTMLDocumentImpl.class, String.class };
-
-
-    /**
-     */
-    public HTMLDocumentImpl()
-    {
-        super();
-        populateElementTypes();
-    }
-
-
-    public synchronized Element getDocumentElement()
-    {
-        Node    html;
-        Node    child;
-        Node    next;
-
-        // The document element is the top-level HTML element of the HTML
-        // document. Only this element should exist at the top level.
-        // If the HTML element is found, all other elements that might
-        // precede it are placed inside the HTML element.
-        html = getFirstChild();
-        while ( html != null )
-        {
-            if ( html instanceof HTMLHtmlElement )
-            {
-                synchronized ( html )
-                {
-                    child = getFirstChild();
-                    while ( child != null && child != html )
-                    {
-                        next = child.getNextSibling();
-                        html.appendChild( child );
-                        child = next;
-                    }
-                }
-                return (HTMLElement) html;
-            }
-            html = html.getNextSibling();
-        }
-
-        // HTML element must exist. Create a new element and dump the
-        // entire contents of the document into it in the same order as
-        // they appear now.
-        html = new HTMLHtmlElementImpl( this, "HTML" );
-        child = getFirstChild();
-        while ( child != null )
-        {
-            next = child.getNextSibling();
-            html.appendChild( child );
-            child = next;
-        }
-        appendChild( html );
-        return (HTMLElement) html;
-    }
-
-
-    /**
-     * Obtains the &lt;HEAD&gt; element in the document, creating one if does
-     * not exist before. The &lt;HEAD&gt; element is the first element in the
-     * &lt;HTML&gt; in the document. The &lt;HTML&gt; element is obtained by
-     * calling {@link #getDocumentElement}. If the element does not exist, one
-     * is created.
-     * <P>
-     * Called by {@link #getTitle}, {@link #setTitle}, {@link #getBody} and
-     * {@link #setBody} to assure the document has the &lt;HEAD&gt; element
-     * correctly placed.
-     *
-     * @return The &lt;HEAD&gt; element
-     */
-    public synchronized HTMLElement getHead()
-    {
-        Node    head;
-        Node    html;
-        Node    child;
-        Node    next;
-
-        // Call getDocumentElement() to get the HTML element that is also the
-        // top-level element in the document. Get the first element in the
-        // document that is called HEAD. Work with that.
-        html = getDocumentElement();
-        synchronized ( html )
-        {
-            head = html.getFirstChild();
-            while ( head != null && ! ( head instanceof HTMLHeadElement ) )
-                head = head.getNextSibling();
-            // HEAD exists but might not be first element in HTML: make sure
-            // it is and return it.
-            if ( head != null )
-            {
-                synchronized ( head )
-                {
-                    child = html.getFirstChild();
-                    while ( child != null && child != head )
-                    {
-                        next = child.getNextSibling();
-                        head.insertBefore( child, head.getFirstChild() );
-                        child = next;
-                    }
-                }
-                return (HTMLElement) head;
-            }
-
-            // Head does not exist, create a new one, place it at the top of the
-            // HTML element and return it.
-            head = new HTMLHeadElementImpl( this, "HEAD" );
-            html.insertBefore( head, html.getFirstChild() );
-        }
-        return (HTMLElement) head;
-    }
-
-
-    public synchronized String getTitle()
-    {
-        HTMLElement head;
-        NodeList    list;
-        Node        title;
-
-        // Get the HEAD element and look for the TITLE element within.
-        // When found, make sure the TITLE is a direct child of HEAD,
-        // and return the title's text (the Text node contained within).
-        head = getHead();
-        title = head.getElementsByTagName( "TITLE" ).item( 0 );
-        list = head.getElementsByTagName( "TITLE" );
-        if ( list.getLength() > 0 ) {
-            title = list.item( 0 );
-            return ( (HTMLTitleElement) title ).getText();
-        }
-        // No TITLE found, return an empty string.
-        return "";
-    }
-
-
-    public synchronized void setTitle( String newTitle )
-    {
-        HTMLElement head;
-        NodeList    list;
-        Node        title;
-
-        // Get the HEAD element and look for the TITLE element within.
-        // When found, make sure the TITLE is a direct child of HEAD,
-        // and set the title's text (the Text node contained within).
-        head = getHead();
-        list = head.getElementsByTagName( "TITLE" );
-        if ( list.getLength() > 0 ) {
-            title = list.item( 0 );
-            if ( title.getParentNode() != head )
-                head.appendChild( title );
-            ( (HTMLTitleElement) title ).setText( newTitle );
-        }
-        else
-        {
-            // No TITLE found, create a new element and place it at the end
-            // of the HEAD element.
-            title = new HTMLTitleElementImpl( this, "TITLE" );
-            ( (HTMLTitleElement) title ).setText( newTitle );
-            head.appendChild( title );
-        }
-    }
-
-
-    public synchronized HTMLElement getBody()
-    {
-        Node    html;
-        Node    head;
-        Node    body;
-        Node    child;
-        Node    next;
-
-        // Call getDocumentElement() to get the HTML element that is also the
-        // top-level element in the document. Get the first element in the
-        // document that is called BODY. Work with that.
-        html = getDocumentElement();
-        head = getHead();
-        synchronized ( html )
-        {
-            body = head.getNextSibling();
-            while ( body != null && ! ( body instanceof HTMLBodyElement )
-                    && ! ( body instanceof HTMLFrameSetElement ) )
-                body = body.getNextSibling();
-
-            // BODY/FRAMESET exists but might not be second element in HTML
-            // (after HEAD): make sure it is and return it.
-            if ( body != null )
-            {
-                synchronized ( body )
-                {
-                    child = head.getNextSibling();
-                    while ( child != null && child != body )
-                    {
-                        next = child.getNextSibling();
-                        body.insertBefore( child, body.getFirstChild() );
-                        child = next;
-                    }
-                }
-                return (HTMLElement) body;
-            }
-
-            // BODY does not exist, create a new one, place it in the HTML element
-            // right after the HEAD and return it.
-            body = new HTMLBodyElementImpl( this, "BODY" );
-            html.appendChild( body );
-        }
-        return (HTMLElement) body;
-    }
-
-
-    public synchronized void setBody( HTMLElement newBody )
-    {
-        Node    html;
-        Node    body;
-        Node    head;
-        Node    child;
-        NodeList list;
-
-        synchronized ( newBody )
-        {
-            // Call getDocumentElement() to get the HTML element that is also the
-            // top-level element in the document. Get the first element in the
-            // document that is called BODY. Work with that.
-            html = getDocumentElement();
-            head = getHead();
-            synchronized ( html )
-            {
-                list = this.getElementsByTagName( "BODY" );
-                if ( list.getLength() > 0 ) {
-                    // BODY exists but might not follow HEAD in HTML. If not,
-                    // make it so and replce it. Start with the HEAD and make
-                    // sure the BODY is the first element after the HEAD.
-                    body = list.item( 0 );
-                    synchronized ( body )
-                    {
-                        child = head;
-                        while ( child != null )
-                        {
-                            if ( child instanceof Element )
-                            {
-                                if ( child != body )
-                                    html.insertBefore( newBody, child );
-                                else
-                                    html.replaceChild( newBody, body );
-                                return;
-                            }
-                            child = child.getNextSibling();
-                        }
-                        html.appendChild( newBody );
-                    }
-                    return;
-                }
-                // BODY does not exist, place it in the HTML element
-                // right after the HEAD.
-                html.appendChild( newBody );
-            }
-        }
-    }
-
-
-    public synchronized Element getElementById( String elementId )
-    {
-        return getElementById( elementId, this );
-    }
-
-
-    public NodeList getElementsByName( String elementName )
-    {
-        return new NameNodeListImpl( this, elementName );
-    }
-
-
-    public final NodeList getElementsByTagName( String tagName )
-    {
-        return super.getElementsByTagName( tagName.toUpperCase() );
-    }
-
-
-    public final NodeList getElementsByTagNameNS( String namespaceURI,
-                                                  String localName )
-    {
-        if ( namespaceURI != null && namespaceURI.length() > 0 )
-            return super.getElementsByTagNameNS( namespaceURI, localName.toUpperCase() );
-        else
-            return super.getElementsByTagName( localName.toUpperCase() );
-    } 
-
-
-    public Element createElementNS( String namespaceURI, String qualifiedName )
-    {
-        if ( namespaceURI == null || namespaceURI.length() == 0 )
-            return createElement( qualifiedName );
-        else
-            return super.createElementNS( namespaceURI, qualifiedName );
-    }
-
-
-    public Element createElement( String tagName )
-        throws DOMException
-    {
-        Class        elemClass;
-        Constructor    cnst;
-
-        // First, make sure tag name is all upper case, next get the associated
-        // element class. If no class is found, generate a generic HTML element.
-        // Do so also if an unexpected exception occurs.
-        tagName = tagName.toUpperCase();
-        elemClass = (Class) _elementTypesHTML.get( tagName );
-        if ( elemClass != null )
-        {
-            // Get the constructor for the element. The signature specifies an
-            // owner document and a tag name. Use the constructor to instantiate
-            // a new object and return it.
-            try
-            {
-                cnst = elemClass.getConstructor( _elemClassSigHTML );
-                return (Element) cnst.newInstance( new Object[] { this, tagName } );
-            }
-            catch ( Exception except )
-            {
-                Throwable thrw;
-
-                if ( except instanceof java.lang.reflect.InvocationTargetException )
-                    thrw = ( (java.lang.reflect.InvocationTargetException) except ).getTargetException();
-                else
-                    thrw = except;
-//                System.out.println( "Exception " + thrw.getClass().getName() );
-//                System.out.println( thrw.getMessage() );
-
-                throw new IllegalStateException( "HTM15 Tag '" + tagName + "' associated with an Element class that failed to construct.\n" + tagName);
-            }
-        }
-        return new HTMLElementImpl( this, tagName );
-    }
-
-
-    /**
-     * Creates an Attribute having this Document as its OwnerDoc.
-     * Overrides {@link DocumentImpl#createAttribute} and returns
-     * and attribute whose name is lower case.
-     *
-     * @param name The name of the attribute
-     * @return An attribute whose name is all lower case
-     * @throws DOMException(INVALID_NAME_ERR) if the attribute name
-     *   is not acceptable
-     */
-    public Attr createAttribute( String name )
-        throws DOMException
-    {
-        return super.createAttribute( name.toLowerCase() );
-    }
-
-
-    public String getReferrer()
-    {
-        // Information not available on server side.
-        return null;
-    }
-
-
-    public String getDomain()
-    {
-        // Information not available on server side.
-        return null;
-    }
-
-
-    public String getURL()
-    {
-        // Information not available on server side.
-        return null;
-    }
-
-
-    public String getCookie()
-    {
-        // Information not available on server side.
-        return null;
-    }
-
-
-    public void setCookie( String cookie )
-    {
-        // Information not available on server side.
-    }
-
-
-    public HTMLCollection getImages()
-    {
-        // For more information see HTMLCollection#collectionMatch
-        if ( _images == null )
-            _images = new HTMLCollectionImpl( getBody(), HTMLCollectionImpl.IMAGE );
-        return _images;
-    }
-
-
-    public HTMLCollection getApplets()
-    {
-        // For more information see HTMLCollection#collectionMatch
-        if ( _applets == null )
-            _applets = new HTMLCollectionImpl( getBody(), HTMLCollectionImpl.APPLET );
-        return _applets;
-    }
-
-
-    public HTMLCollection getLinks()
-    {
-        // For more information see HTMLCollection#collectionMatch
-        if ( _links == null )
-            _links = new HTMLCollectionImpl( getBody(), HTMLCollectionImpl.LINK );
-        return _links;
-    }
-
-
-    public HTMLCollection getForms()
-    {
-        // For more information see HTMLCollection#collectionMatch
-        if ( _forms == null )
-            _forms = new HTMLCollectionImpl( getBody(), HTMLCollectionImpl.FORM );
-        return _forms;
-    }
-
-
-    public HTMLCollection getAnchors()
-    {
-        // For more information see HTMLCollection#collectionMatch
-        if ( _anchors == null )
-            _anchors = new HTMLCollectionImpl( getBody(), HTMLCollectionImpl.ANCHOR );
-        return _anchors;
-    }
-
-
-    public void open()
-    {
-        // When called an in-memory is prepared. The document tree is still
-        // accessible the old way, until this writer is closed.
-        if ( _writer == null )
-            _writer = new StringWriter();
-    }
-
-
-    public void close()
-    {
-        // ! NOT IMPLEMENTED, REQUIRES PARSER !
-        if ( _writer != null )
-        {
-            _writer = null;
-        }
-    }
-
-
-    public void write( String text )
-    {
-        // Write a string into the in-memory writer.
-        if ( _writer != null )
-            _writer.write( text );
-    }
-
-
-    public void writeln( String text )
-    {
-        // Write a line into the in-memory writer.
-        if ( _writer != null )
-            _writer.write( text + "\n" );
-    }
-
-
-    public Node cloneNode( boolean deep )
-    {
-        HTMLDocumentImpl    clone;
-        NodeImpl            node;
-        
-        clone = new HTMLDocumentImpl();
-        if ( deep ) {
-            node = (NodeImpl) getFirstChild();
-            while ( node != null ) {
-                clone.appendChild( clone.importNode( node, true ) );
-                node = (NodeImpl) node.getNextSibling();
-            }
-        }
-        return clone;
-    }
-
-
-    /**
-     * Recursive method retreives an element by its <code>id</code> attribute.
-     * Called by {@link #getElementById(String)}.
-     *
-     * @param elementId The <code>id</code> value to look for
-     * @return The node in which to look for
-     */
-    private Element getElementById( String elementId, Node node )
-    {
-        Node    child;
-        Element    result;
-
-        child = node.getFirstChild();
-        while ( child != null )
-        {
-            if ( child instanceof Element )
-            {
-                if ( elementId.equals( ( (Element) child ).getAttribute( "id" ) ) )
-                    return (Element) child;
-                result = getElementById( elementId, child );
-                if ( result != null )
-                    return result;
-            }
-            child = child.getNextSibling();
-        }
-        return null;
-    }
-
-
-    /**
-     * Called by the constructor to populate the element types list (see {@link
-     * #_elementTypesHTML}). Will be called multiple times but populate the list
-     * only the first time. Replacement for static constructor.
-     */
-    private static void populateElementTypes()
-    {
-        // This class looks like it is due to some strange
-        // (read: inconsistent) JVM bugs.
-        // Initially all this code was placed in the static constructor,
-        // but that caused some early JVMs (1.1) to go mad, and if a
-        // class could not be found (as happened during development),
-        // the JVM would die.
-        // Bertrand Delacretaz <bdelacretaz@worldcom.ch> pointed out
-        // several configurations where HTMLAnchorElementImpl.class
-        // failed, forcing me to revert back to Class.forName().
-        
-        if ( _elementTypesHTML != null )
-            return;
-        _elementTypesHTML = new Hashtable( 63 );
-        populateElementType( "A", "HTMLAnchorElementImpl" );
-        populateElementType( "APPLET", "HTMLAppletElementImpl" );
-        populateElementType( "AREA", "HTMLAreaElementImpl" );
-        populateElementType( "BASE",  "HTMLBaseElementImpl" );
-        populateElementType( "BASEFONT", "HTMLBaseFontElementImpl" );
-        populateElementType( "BLOCKQUOTE", "HTMLQuoteElementImpl" );
-        populateElementType( "BODY", "HTMLBodyElementImpl" );
-        populateElementType( "BR", "HTMLBRElementImpl" );
-        populateElementType( "BUTTON", "HTMLButtonElementImpl" );
-        populateElementType( "DEL", "HTMLModElementImpl" );
-        populateElementType( "DIR", "HTMLDirectoryElementImpl" );
-        populateElementType( "DIV",  "HTMLDivElementImpl" );
-        populateElementType( "DL", "HTMLDListElementImpl" );
-        populateElementType( "FIELDSET", "HTMLFieldSetElementImpl" );
-        populateElementType( "FONT", "HTMLFontElementImpl" );
-        populateElementType( "FORM", "HTMLFormElementImpl" );
-        populateElementType( "FRAME","HTMLFrameElementImpl" );
-        populateElementType( "FRAMESET", "HTMLFrameSetElementImpl" );
-        populateElementType( "HEAD", "HTMLHeadElementImpl" );
-        populateElementType( "H1", "HTMLHeadingElementImpl" );
-        populateElementType( "H2", "HTMLHeadingElementImpl" );
-        populateElementType( "H3", "HTMLHeadingElementImpl" );
-        populateElementType( "H4", "HTMLHeadingElementImpl" );
-        populateElementType( "H5", "HTMLHeadingElementImpl" );
-        populateElementType( "H6", "HTMLHeadingElementImpl" );
-        populateElementType( "HR", "HTMLHRElementImpl" );
-        populateElementType( "HTML", "HTMLHtmlElementImpl" );
-        populateElementType( "IFRAME", "HTMLIFrameElementImpl" );
-        populateElementType( "IMG", "HTMLImageElementImpl" );
-        populateElementType( "INPUT", "HTMLInputElementImpl" );
-        populateElementType( "INS", "HTMLModElementImpl" );
-        populateElementType( "ISINDEX", "HTMLIsIndexElementImpl" );
-        populateElementType( "LABEL", "HTMLLabelElementImpl" );
-        populateElementType( "LEGEND", "HTMLLegendElementImpl" );
-        populateElementType( "LI", "HTMLLIElementImpl" );
-        populateElementType( "LINK", "HTMLLinkElementImpl" );
-        populateElementType( "MAP", "HTMLMapElementImpl" );
-        populateElementType( "MENU", "HTMLMenuElementImpl" );
-        populateElementType( "META", "HTMLMetaElementImpl" );
-        populateElementType( "OBJECT", "HTMLObjectElementImpl" );
-        populateElementType( "OL", "HTMLOListElementImpl" );
-        populateElementType( "OPTGROUP", "HTMLOptGroupElementImpl" );
-        populateElementType( "OPTION", "HTMLOptionElementImpl" );
-        populateElementType( "P", "HTMLParagraphElementImpl" );
-        populateElementType( "PARAM", "HTMLParamElementImpl" );
-        populateElementType( "PRE", "HTMLPreElementImpl" );
-        populateElementType( "Q", "HTMLQuoteElementImpl" );
-        populateElementType( "SCRIPT", "HTMLScriptElementImpl" );
-        populateElementType( "SELECT", "HTMLSelectElementImpl" );
-        populateElementType( "STYLE", "HTMLStyleElementImpl" );
-        populateElementType( "TABLE", "HTMLTableElementImpl" );
-        populateElementType( "CAPTION", "HTMLTableCaptionElementImpl" );
-        populateElementType( "TD", "HTMLTableCellElementImpl" );
-        populateElementType( "TH", "HTMLTableCellElementImpl" );
-        populateElementType( "COL", "HTMLTableColElementImpl" );
-        populateElementType( "COLGROUP", "HTMLTableColElementImpl" );
-        populateElementType( "TR", "HTMLTableRowElementImpl" );
-        populateElementType( "TBODY", "HTMLTableSectionElementImpl" );
-        populateElementType( "THEAD", "HTMLTableSectionElementImpl" );
-        populateElementType( "TFOOT", "HTMLTableSectionElementImpl" );
-        populateElementType( "TEXTAREA", "HTMLTextAreaElementImpl" );
-        populateElementType( "TITLE", "HTMLTitleElementImpl" );
-        populateElementType( "UL", "HTMLUListElementImpl" );
-    }
-    
-    
-    private static void populateElementType( String tagName, String className )
-    {
-        try {
-            _elementTypesHTML.put( tagName, Class.forName( "org.apache.html.dom." + className ) );
-        } catch ( ClassNotFoundException except ) {
-            new RuntimeException( "HTM019 OpenXML Error: Could not find class " + className + " implementing HTML element " + tagName
-                                  + "\n" + className + "\t" + tagName);
-        }
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLElementImpl.java b/src/org/apache/html/dom/HTMLElementImpl.java
deleted file mode 100755
index d347a15..0000000
--- a/src/org/apache/html/dom/HTMLElementImpl.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-import org.apache.xerces.dom.ElementImpl;
-
-
-/**
- * Implements an HTML-specific element, an {@link org.w3c.dom.Element} that
- * will only appear inside HTML documents. This element extends {@link
- * org.apache.xerces.dom.ElementImpl} by adding methods for directly
- * manipulating HTML-specific attributes. All HTML elements gain access to
- * the <code>id</code>, <code>title</code>, <code>lang</code>,
- * <code>dir</code> and <code>class</code> attributes. Other elements
- * add their own specific attributes.
- * 
- * 
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLElement
- */
-public class HTMLElementImpl
-    extends ElementImpl
-    implements HTMLElement
-{
-
-
-    /**
-     * Constructor required owner document and element tag name. Will be called
-     * by the constructor of specific element types but with a known tag name.
-     * Assures that the owner document is an HTML element.
-     * 
-     * @param owner The owner HTML document
-     * @param tagName The element's tag name
-     */
-    HTMLElementImpl( HTMLDocumentImpl owner, String tagName )
-    {
-        super( owner, tagName.toUpperCase() );
-    }
-    
-    
-    public String getId()
-    {
-        return getAttribute( "id" );
-    }
-    
-    
-    public void setId( String id )
-    {
-        setAttribute( "id", id );
-    }
-    
-    
-    public String getTitle()
-    {
-        return getAttribute( "title" );
-    }
-    
-    
-    public void setTitle( String title )
-    {
-        setAttribute( "title", title );
-    }
-    
-    
-    public String getLang()
-    {
-        return getAttribute( "lang" );
-    }
-    
-    
-    public void setLang( String lang )
-    {
-        setAttribute( "lang", lang );
-    }
-    
-    
-    public String getDir()
-    {
-        return getAttribute( "dir" );
-    }
-    
-    
-    public void setDir( String dir )
-    {
-        setAttribute( "dir", dir );
-    }
-
-    
-    public String getClassName()
-    {
-        return getAttribute( "class" );
-    }
-
-    
-    public void setClassName( String className )
-    {
-        setAttribute( "class", className );
-    }
-    
-    
-    /**
-     * Convenience method used to translate an attribute value into an integer
-     * value. Returns the integer value or zero if the attribute is not a
-     * valid numeric string.
-     * 
-     * @param value The value of the attribute
-     * @return The integer value, or zero if not a valid numeric string
-     */
-    int getInteger( String value )
-    {
-        try
-        {
-            return Integer.parseInt( value );
-        }
-        catch ( NumberFormatException except )
-        {
-            return 0;
-        }
-    }
-    
-    
-    /**
-     * Convenience method used to translate an attribute value into a boolean
-     * value. If the attribute has an associated value (even an empty string),
-     * it is set and true is returned. If the attribute does not exist, false
-     * is returend.
-     * 
-     * @param value The value of the attribute
-     * @return True or false depending on whether the attribute has been set
-     */
-    boolean getBinary( String name )
-    {
-        return ( getAttributeNode( name ) != null );
-    }
-    
-    
-    /**
-     * Convenience method used to set a boolean attribute. If the value is true,
-     * the attribute is set to an empty string. If the value is false, the attribute
-     * is removed. HTML 4.0 understands empty strings as set attributes.
-     * 
-     * @param name The name of the attribute
-     * @param value The value of the attribute
-     */
-    void setAttribute( String name, boolean value )
-    {
-        if ( value )
-            setAttribute( name, name );
-        else
-            removeAttribute( name );
-    }
-
-
-    public Attr getAttributeNode( String attrName )
-    {
-	return super.getAttributeNode( attrName.toLowerCase() );
-    }
-
-
-    public Attr getAttributeNodeNS( String namespaceURI,
-				    String localName )
-    {
-	if ( namespaceURI != null && namespaceURI.length() > 0 )
-	    return super.getAttributeNodeNS( namespaceURI, localName );
-	else
-	    return super.getAttributeNode( localName.toLowerCase() );
-    }
-    
-    
-    public String getAttribute( String attrName )
-    {
-	return super.getAttribute( attrName.toLowerCase() );
-    }
-
-
-    public String getAttributeNS( String namespaceURI,
-				  String localName )
-    {
-	if ( namespaceURI != null && namespaceURI.length() > 0 )
-	    return super.getAttributeNS( namespaceURI, localName );
-	else
-	    return super.getAttribute( localName.toLowerCase() );
-    }
-
-
-    public final NodeList getElementsByTagName( String tagName )
-    {
-	return super.getElementsByTagName( tagName.toUpperCase() );
-    }
-
-
-    public final NodeList getElementsByTagNameNS( String namespaceURI,
-					          String localName )
-    {
-	if ( namespaceURI != null && namespaceURI.length() > 0 )
-	    return super.getElementsByTagNameNS( namespaceURI, localName.toUpperCase() );
-	else
-	    return super.getElementsByTagName( localName.toUpperCase() );
-    } 
-
-
-    /**
-     * Convenience method used to capitalize a one-off attribute value before it
-     * is returned. For example, the align values "LEFT" and "left" will both
-     * return as "Left".
-     * 
-     * @param value The value of the attribute
-     * @return The capitalized value
-     */
-    String capitalize( String value )
-    {
-        char[]    chars;
-        int        i;
-        
-        // Convert string to charactares. Convert the first one to upper case,
-        // the other characters to lower case, and return the converted string.
-        chars = value.toCharArray();
-        if ( chars.length > 0 )
-        {
-            chars[ 0 ] = Character.toUpperCase( chars[ 0 ] );
-            for ( i = 1 ; i < chars.length ; ++i )
-                chars[ i ] = Character.toLowerCase( chars[ i ] );
-            return String.valueOf( chars );
-        }
-        return value;
-    }
-    
-
-    /**
-     * Convenience method used to capitalize a one-off attribute value before it
-     * is returned. For example, the align values "LEFT" and "left" will both
-     * return as "Left".
-     * 
-     * @param name The name of the attribute
-     * @return The capitalized value
-     */
-    String getCapitalized( String name )
-    {
-        String    value;
-        char[]    chars;
-        int        i;
-        
-        value = getAttribute( name );
-        if ( value != null )
-        {
-            // Convert string to charactares. Convert the first one to upper case,
-            // the other characters to lower case, and return the converted string.
-            chars = value.toCharArray();
-            if ( chars.length > 0 )
-            {
-                chars[ 0 ] = Character.toUpperCase( chars[ 0 ] );
-                for ( i = 1 ; i < chars.length ; ++i )
-                    chars[ i ] = Character.toLowerCase( chars[ i ] );
-                return String.valueOf( chars );
-            }
-        }
-        return value;
-    }
-
-    
-    /**
-     * Convenience method returns the form in which this form element is contained.
-     * This method is exposed for form elements through the DOM API, but other
-     * elements have no access to it through the API.
-     */
-    public HTMLFormElement getForm()
-    {
-        Node    parent;
-        
-        parent = getParentNode(); 
-        while ( parent != null )
-        {
-            if ( parent instanceof HTMLFormElement )
-                return (HTMLFormElement) parent;
-            parent = parent.getParentNode();
-        }
-        return null;
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLFieldSetElementImpl.java b/src/org/apache/html/dom/HTMLFieldSetElementImpl.java
deleted file mode 100755
index 6f5fafc..0000000
--- a/src/org/apache/html/dom/HTMLFieldSetElementImpl.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLFieldSetElement
- * @see ElementImpl
- */
-public final class HTMLFieldSetElementImpl
-    extends HTMLElementImpl
-    implements HTMLFieldSetElement, HTMLFormControl
-{
-
-
-      /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLFieldSetElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-  
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLFontElementImpl.java b/src/org/apache/html/dom/HTMLFontElementImpl.java
deleted file mode 100755
index ca2a86c..0000000
--- a/src/org/apache/html/dom/HTMLFontElementImpl.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLFontElement
- * @see ElementImpl
- */
-public final class HTMLFontElementImpl
-    extends HTMLElementImpl
-    implements HTMLFontElement
-{
-
-    
-    public String getColor()
-    {
-        return capitalize( getAttribute( "color" ) );
-    }
-    
-    
-    public void setColor( String color )
-    {
-        setAttribute( "color", color );
-    }
-    
-    
-    public String getFace()
-    {
-        return capitalize( getAttribute( "face" ) );
-    }
-    
-    
-    public void setFace( String face )
-    {
-        setAttribute( "face", face );
-    }
-    
-    
-    public String getSize()
-    {
-        return getAttribute( "size" );
-    }
-    
-    
-    public void setSize( String size )
-    {
-        setAttribute( "size", size );
-    }
-
-    
-    public HTMLFontElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-  
-
-}
diff --git a/src/org/apache/html/dom/HTMLFormControl.java b/src/org/apache/html/dom/HTMLFormControl.java
deleted file mode 100755
index 43b62d4..0000000
--- a/src/org/apache/html/dom/HTMLFormControl.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-/**
- * Identifies control in a form, so they may be collected in a form elements
- * collection. All form control elements implement this empty interface.
- * 
- * 
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- */
-public interface HTMLFormControl
-{
-}
diff --git a/src/org/apache/html/dom/HTMLFormElementImpl.java b/src/org/apache/html/dom/HTMLFormElementImpl.java
deleted file mode 100755
index b859dfd..0000000
--- a/src/org/apache/html/dom/HTMLFormElementImpl.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLFormElement
- * @see ElementImpl
- */
-public final class HTMLFormElementImpl
-    extends HTMLElementImpl
-    implements HTMLFormElement
-{
-
-    
-    public HTMLCollection getElements()
-    {
-        if ( _elements == null )
-            _elements = new HTMLCollectionImpl( this, HTMLCollectionImpl.ELEMENT );
-        return _elements;
-    }
-  
-
-    public int getLength()
-    {
-        return getElements().getLength();
-    }
-  
-  
-    public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-
-    
-    public String getAcceptCharset()
-    {
-        return getAttribute( "accept-charset" );
-    }
-    
-    
-    public void setAcceptCharset( String acceptCharset )
-    {
-        setAttribute( "accept-charset", acceptCharset );
-    }
-
-  
-      public String getAction()
-    {
-        return getAttribute( "action" );
-    }
-    
-    
-    public void setAction( String action )
-    {
-        setAttribute( "action", action );
-    }
-  
-  
-      public String getEnctype()
-    {
-        return getAttribute( "enctype" );
-    }
-    
-    
-    public void setEnctype( String enctype )
-    {
-        setAttribute( "enctype", enctype );
-    }
-
-    
-      public String getMethod()
-    {
-        return capitalize( getAttribute( "method" ) );
-    }
-    
-    
-    public void setMethod( String method )
-    {
-        setAttribute( "method", method );
-    }
-  
-  
-    public String getTarget()
-    {
-        return getAttribute( "target" );
-    }
-    
-    
-    public void setTarget( String target )
-    {
-        setAttribute( "target", target );
-    }
-
-    
-    public void submit()
-    {
-        // No scripting in server-side DOM. This method is moot.
-    }
-
-    
-    public void reset()
-    {
-        // No scripting in server-side DOM. This method is moot.
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLFormElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-  
-    
-    /**
-     * Collection of all elements contained in this FORM.
-     */
-    private HTMLCollectionImpl    _elements;
-    
-}
-
diff --git a/src/org/apache/html/dom/HTMLFrameElementImpl.java b/src/org/apache/html/dom/HTMLFrameElementImpl.java
deleted file mode 100755
index fcfeb44..0000000
--- a/src/org/apache/html/dom/HTMLFrameElementImpl.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLFrameElement
- * @see ElementImpl
- */
-public final class HTMLFrameElementImpl
-    extends HTMLElementImpl
-    implements HTMLFrameElement
-{
-
-    
-    public String getFrameBorder()
-    {
-        return getAttribute( "frameborder" );
-    }
-    
-    
-    public void setFrameBorder( String frameBorder )
-    {
-        setAttribute( "frameborder", frameBorder );
-    }
-  
-  
-    public String getLongDesc()
-    {
-        return getAttribute( "longdesc" );
-    }
-    
-    
-    public void setLongDesc( String longDesc )
-    {
-        setAttribute( "longdesc", longDesc );
-    }
-  
-  
-    public String getMarginHeight()
-    {
-        return getAttribute( "marginheight" );
-    }
-    
-    
-    public void setMarginHeight( String marginHeight )
-    {
-        setAttribute( "marginheight", marginHeight );
-    }
-  
-  
-    public String getMarginWidth()
-    {
-        return getAttribute( "marginwidth" );
-    }
-    
-    
-    public void setMarginWidth( String marginWidth )
-    {
-        setAttribute( "marginwidth", marginWidth );
-    }
-  
-  
-    public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-
-    
-    public boolean getNoResize()
-    {
-        return getBinary( "noresize" );
-    }
-    
-    
-    public void setNoResize( boolean noResize )
-    {
-        setAttribute( "noresize", noResize );
-    }
-
-    
-    public String getScrolling()
-    {
-        return capitalize( getAttribute( "scrolling" ) );
-    }
-    
-    
-    public void setScrolling( String scrolling )
-    {
-        setAttribute( "scrolling", scrolling );
-    }
-  
-  
-    public String getSrc()
-    {
-        return getAttribute( "src" );
-    }
-    
-    
-    public void setSrc( String src )
-    {
-        setAttribute( "src", src );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLFrameElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-  
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLFrameSetElementImpl.java b/src/org/apache/html/dom/HTMLFrameSetElementImpl.java
deleted file mode 100755
index ff083e8..0000000
--- a/src/org/apache/html/dom/HTMLFrameSetElementImpl.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLFrameSetElement
- * @see ElementImpl
- */
-public final class HTMLFrameSetElementImpl
-    extends HTMLElementImpl
-    implements HTMLFrameSetElement
-{
-
-    
-    public String getCols()
-    {
-        return getAttribute( "cols" );
-    }
-    
-    
-    public void setCols( String cols )
-    {
-        setAttribute( "cols", cols );
-    }
-
-    
-    public String getRows()
-    {
-        return getAttribute( "rows" );
-    }
-    
-    
-    public void setRows( String rows )
-    {
-        setAttribute( "rows", rows );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLFrameSetElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-  
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLHRElementImpl.java b/src/org/apache/html/dom/HTMLHRElementImpl.java
deleted file mode 100755
index d689de2..0000000
--- a/src/org/apache/html/dom/HTMLHRElementImpl.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLHRElement
- * @see ElementImpl
- */
-public final class HTMLHRElementImpl
-    extends HTMLElementImpl
-    implements HTMLHRElement
-{
-
-    
-    public String getAlign()
-    {
-        return capitalize( getAttribute( "align" ) );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-  
-    
-    public boolean getNoShade()
-    {
-        return getBinary( "noshade" );
-    }
-    
-    
-    public void setNoShade( boolean noShade )
-    {
-        setAttribute( "noshade", noShade );
-    }
-
-    
-    public String getSize()
-    {
-        return getAttribute( "size" );
-    }
-    
-    
-    public void setSize( String size )
-    {
-        setAttribute( "size", size );
-    }
-  
-  
-      public String getWidth()
-    {
-        return getAttribute( "width" );
-    }
-    
-    
-    public void setWidth( String width )
-    {
-        setAttribute( "width", width );
-    }
-    
-
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLHRElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLHeadElementImpl.java b/src/org/apache/html/dom/HTMLHeadElementImpl.java
deleted file mode 100755
index 5e5212b..0000000
--- a/src/org/apache/html/dom/HTMLHeadElementImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLHeadElement
- * @see ElementImpl
- */
-public final class HTMLHeadElementImpl
-    extends HTMLElementImpl
-    implements HTMLHeadElement
-{
-
-    
-    public String getProfile()
-    {
-        return getAttribute( "profile" );
-    }
-    
-    
-    public void setProfile( String profile )
-    {
-        setAttribute( "profile", profile );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLHeadElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLHeadingElementImpl.java b/src/org/apache/html/dom/HTMLHeadingElementImpl.java
deleted file mode 100755
index ce26496..0000000
--- a/src/org/apache/html/dom/HTMLHeadingElementImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLHeadingElement
- * @see ElementImpl
- */
-public final class HTMLHeadingElementImpl
-    extends HTMLElementImpl
-    implements HTMLHeadingElement
-{
-
-    
-    public String getAlign()
-    {
-        return getCapitalized( "align" );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-  
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLHeadingElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLHtmlElementImpl.java b/src/org/apache/html/dom/HTMLHtmlElementImpl.java
deleted file mode 100755
index 422d33f..0000000
--- a/src/org/apache/html/dom/HTMLHtmlElementImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLHtmlElement
- * @see ElementImpl
- */
-public final class HTMLHtmlElementImpl
-    extends HTMLElementImpl
-    implements HTMLHtmlElement
-{
-
-    
-    public String getVersion()
-    {
-        return capitalize( getAttribute( "version" ) );
-    }
-    
-    
-    public void setVersion( String version )
-    {
-        setAttribute( "version", version );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLHtmlElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLIFrameElementImpl.java b/src/org/apache/html/dom/HTMLIFrameElementImpl.java
deleted file mode 100755
index 8afe316..0000000
--- a/src/org/apache/html/dom/HTMLIFrameElementImpl.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLIFrameElement
- * @see ElementImpl
- */
-public final class HTMLIFrameElementImpl
-    extends HTMLElementImpl
-    implements HTMLIFrameElement
-{
-
-    
-    public String getAlign()
-    {
-        return capitalize( getAttribute( "align" ) );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-  
-    
-    public String getFrameBorder()
-    {
-        return getAttribute( "frameborder" );
-    }
-    
-    
-    public void setFrameBorder( String frameBorder )
-    {
-        setAttribute( "frameborder", frameBorder );
-    }
-
-    
-    public String getHeight()
-    {
-        return getAttribute( "height" );
-    }
-    
-    
-    public void setHeight( String height )
-    {
-        setAttribute( "height", height );
-    }
-  
-    public String getLongDesc()
-    {
-        return getAttribute( "longdesc" );
-    }
-    
-    
-    public void setLongDesc( String longDesc )
-    {
-        setAttribute( "longdesc", longDesc );
-    }
-  
-  
-    public String getMarginHeight()
-    {
-        return getAttribute( "marginheight" );
-    }
-    
-    
-    public void setMarginHeight( String marginHeight )
-    {
-        setAttribute( "marginheight", marginHeight );
-    }
-  
-  
-    public String getMarginWidth()
-    {
-        return getAttribute( "marginwidth" );
-    }
-    
-    
-    public void setMarginWidth( String marginWidth )
-    {
-        setAttribute( "marginwidth", marginWidth );
-    }
-
-  
-      public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-
-    
-    public String getScrolling()
-    {
-        return capitalize( getAttribute( "scrolling" ) );
-    }
-    
-    
-    public void setScrolling( String scrolling )
-    {
-        setAttribute( "scrolling", scrolling );
-    }
-    
-  
-       public String getSrc()
-    {
-        return getAttribute( "src" );
-    }
-    
-    
-    public void setSrc( String src )
-    {
-        setAttribute( "src", src );
-    }
-
-
-      public String getWidth()
-    {
-        return getAttribute( "width" );
-    }
-    
-    
-    public void setWidth( String width )
-    {
-        setAttribute( "width", width );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLIFrameElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLImageElementImpl.java b/src/org/apache/html/dom/HTMLImageElementImpl.java
deleted file mode 100755
index 4543072..0000000
--- a/src/org/apache/html/dom/HTMLImageElementImpl.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLImageElement
- * @see ElementImpl
- */
-public final class HTMLImageElementImpl
-    extends HTMLElementImpl
-    implements HTMLImageElement
-{
-
-    
-       public String getLowSrc()
-    {
-        return getAttribute( "lowsrc" );
-    }
-    
-    
-    public void setLowSrc( String lowSrc )
-    {
-        setAttribute( "lowsrc", lowSrc );
-    }
-
-  
-       public String getSrc()
-    {
-        return getAttribute( "src" );
-    }
-    
-    
-    public void setSrc( String src )
-    {
-        setAttribute( "src", src );
-    }
-
-    
-      public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-
-    
-    public String getAlign()
-    {
-        return capitalize( getAttribute( "align" ) );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-  
-    
-    public String getAlt()
-    {
-        return getAttribute( "alt" );
-    }
-    
-    
-    public void setAlt( String alt )
-    {
-        setAttribute( "alt", alt );
-    }
-
-    
-    public String getBorder()
-    {
-        return getAttribute( "border" );
-    }
-    
-    
-    public void setBorder( String border )
-    {
-        setAttribute( "border", border );
-    }
-
-  
-      public String getHeight()
-    {
-        return getAttribute( "height" );
-    }
-    
-    
-    public void setHeight( String height )
-    {
-        setAttribute( "height", height );
-    }
-
-    
-    public String getHspace()
-    {
-        return getAttribute( "hspace" );
-    }
-    
-    
-    public void setHspace( String hspace )
-    {
-        setAttribute( "hspace", hspace );
-    }
-    
-  
-    public boolean getIsMap()
-    {
-        return getBinary( "ismap" );
-    }
-    
-    
-    public void setIsMap( boolean isMap )
-    {
-        setAttribute( "ismap", isMap );
-    }
-
-    
-    public String getLongDesc()
-    {
-        return getAttribute( "longdesc" );
-    }
-    
-    
-    public void setLongDesc( String longDesc )
-    {
-        setAttribute( "longdesc", longDesc );
-    }
-    
-  
-    public String getUseMap()
-    {
-        return getAttribute( "useMap" );
-    }
-    
-    
-    public void setUseMap( String useMap )
-    {
-        setAttribute( "useMap", useMap );
-    }
-    
-
-    public String getVspace()
-    {
-        return getAttribute( "vspace" );
-    }
-    
-    
-    public void setVspace( String vspace )
-    {
-        setAttribute( "vspace", vspace );
-    }
-
-  
-      public String getWidth()
-    {
-        return getAttribute( "width" );
-    }
-    
-    
-    public void setWidth( String width )
-    {
-        setAttribute( "width", width );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLImageElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLInputElementImpl.java b/src/org/apache/html/dom/HTMLInputElementImpl.java
deleted file mode 100755
index 54253bf..0000000
--- a/src/org/apache/html/dom/HTMLInputElementImpl.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLInputElement
- * @see ElementImpl
- */
-public final class HTMLInputElementImpl
-    extends HTMLElementImpl
-    implements HTMLInputElement, HTMLFormControl
-{
-    
-    
-    public String getDefaultValue()
-    {
-        // ! NOT FULLY IMPLEMENTED !
-        return getAttribute( "defaultValue" );
-    }
-    
-    
-    public void setDefaultValue( String defaultValue )
-    {
-        // ! NOT FULLY IMPLEMENTED !
-        setAttribute( "defaultValue", defaultValue );
-    }
-    
-    
-    public boolean getDefaultChecked()
-    {
-        // ! NOT FULLY IMPLEMENTED !
-        return getBinary( "defaultChecked" );
-    }
-    
-    
-    public void setDefaultChecked( boolean defaultChecked )
-    {
-        // ! NOT FULLY IMPLEMENTED !
-        setAttribute( "defaultChecked", defaultChecked );
-    }
-  
-    
-    public String getAccept()
-    {
-        return getAttribute( "accept" );
-    }
-    
-    
-    public void setAccept( String accept )
-    {
-        setAttribute( "accept", accept );
-    }   
-    
-    
-    public String getAccessKey()
-    {
-        String    accessKey;
-        
-        // Make sure that the access key is a single character.
-        accessKey = getAttribute( "accesskey" );
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        return accessKey;
-    }
-    
-    
-    public void setAccessKey( String accessKey )
-    {
-        // Make sure that the access key is a single character.    
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        setAttribute( "accesskey", accessKey );
-    }
-    
-    
-    public String getAlign()
-    {
-        return capitalize( getAttribute( "align" ) );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-    
-    
-    public String getAlt()
-    {
-        return getAttribute( "alt" );
-    }
-    
-    
-    public void setAlt( String alt )
-    {
-        setAttribute( "alt", alt );
-    }
-    
-    
-    public boolean getChecked()
-    {
-        return getBinary( "checked" );
-    }
-    
-    
-    public void setChecked( boolean checked )
-    {
-        setAttribute( "checked", checked );
-    }
-  
-    
-    public boolean getDisabled()
-    {
-        return getBinary( "disabled" );
-    }
-    
-    
-    public void setDisabled( boolean disabled )
-    {
-        setAttribute( "disabled", disabled );
-    }
-    
-    
-    public int getMaxLength()
-    {
-        return getInteger( getAttribute( "maxlength" ) );
-    }
-    
-    
-    public void setMaxLength( int maxLength )
-    {
-        setAttribute( "maxlength", String.valueOf( maxLength ) );
-    }
-    
-    
-    public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-    
-    
-    public boolean getReadOnly()
-    {
-        return getBinary( "readonly" );
-    }
-    
-    
-    public void setReadOnly( boolean readOnly )
-    {
-        setAttribute( "readonly", readOnly );
-    }
-    
-    
-    public String getSize()
-    {
-        return getAttribute( "size" );
-    }
-    
-    
-    public void setSize( String size )
-    {
-        setAttribute( "size", size );
-    }
-    
-    
-    public String getSrc()
-    {
-        return getAttribute( "src" );
-    }
-    
-    
-    public void setSrc( String src )
-    {
-        setAttribute( "src", src );
-    }
-    
-    
-      public int getTabIndex()
-    {
-        try
-        {
-            return Integer.parseInt( getAttribute( "tabindex" ) );
-        }
-        catch ( NumberFormatException except )
-        {
-            return 0;
-        }
-    }
-    
-    
-    public void setTabIndex( int tabIndex )
-    {
-        setAttribute( "tabindex", String.valueOf( tabIndex ) );
-    }
-
-  
-    public String getType()
-    {
-        return getAttribute( "type" );
-    }
-    
-    
-    public String getUseMap()
-    {
-        return getAttribute( "useMap" );
-    }
-    
-    
-    public void setUseMap( String useMap )
-    {
-        setAttribute( "useMap", useMap );
-    }
-    
-    
-    public String getValue()
-    {
-        return getAttribute( "value" );
-    }
-    
-    
-    public void setValue( String value )
-    {
-        setAttribute( "value", value );
-    }
-    
-    
-    public void blur()
-    {
-        // No scripting in server-side DOM. This method is moot.
-    }
-    
-    
-    public void focus()
-    {
-        // No scripting in server-side DOM. This method is moot.
-    }
-    
-    
-    public void select()
-    {
-        // No scripting in server-side DOM. This method is moot.
-    }
-    
-    
-    public void click()
-    {
-        // No scripting in server-side DOM. This method is moot.
-    }
-
-  
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLInputElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
-
diff --git a/src/org/apache/html/dom/HTMLIsIndexElementImpl.java b/src/org/apache/html/dom/HTMLIsIndexElementImpl.java
deleted file mode 100755
index ae44669..0000000
--- a/src/org/apache/html/dom/HTMLIsIndexElementImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLIsIndexElement
- * @see ElementImpl
- */
-public final class HTMLIsIndexElementImpl
-    extends HTMLElementImpl
-    implements HTMLIsIndexElement
-{
-
-    
-    public String getPrompt()
-    {
-        return getAttribute( "prompt" );
-    }
-    
-    
-    public void setPrompt( String prompt )
-    {
-        setAttribute( "prompt", prompt );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLIsIndexElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLLIElementImpl.java b/src/org/apache/html/dom/HTMLLIElementImpl.java
deleted file mode 100755
index dfd3f07..0000000
--- a/src/org/apache/html/dom/HTMLLIElementImpl.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLLIElement
- * @see ElementImpl
- */
-public final class HTMLLIElementImpl
-    extends HTMLElementImpl
-	    implements HTMLLIElement
-{
-
-    
-    public String getType()
-    {
-        return getAttribute( "type" );
-    }
-    
-    
-    public void setType( String type )
-    {
-        setAttribute( "type", type );
-    }
-        
-
-    public int getValue()
-    {
-        return getInteger( getAttribute( "value" ) );
-    }
-
-    
-    public void setValue( int value )
-    {
-        setAttribute( "value", String.valueOf( value ) );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLLIElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLLabelElementImpl.java b/src/org/apache/html/dom/HTMLLabelElementImpl.java
deleted file mode 100755
index f597a83..0000000
--- a/src/org/apache/html/dom/HTMLLabelElementImpl.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLLabelElement
- * @see ElementImpl
- */
-public final class HTMLLabelElementImpl
-    extends HTMLElementImpl
-    implements HTMLLabelElement, HTMLFormControl
-{
-
-    
-    public String getAccessKey()
-    {
-        String    accessKey;
-        
-        // Make sure that the access key is a single character.
-        accessKey = getAttribute( "accesskey" );
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        return accessKey;
-    }
-    
-    
-    public void setAccessKey( String accessKey )
-    {
-        // Make sure that the access key is a single character.
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        setAttribute( "accesskey", accessKey );
-    }
-
-    
-       public String getHtmlFor()
-    {
-        return getAttribute( "for" );
-    }
-    
-    
-    public void setHtmlFor( String htmlFor )
-    {
-        setAttribute( "for", htmlFor );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLLabelElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLLegendElementImpl.java b/src/org/apache/html/dom/HTMLLegendElementImpl.java
deleted file mode 100755
index a434d20..0000000
--- a/src/org/apache/html/dom/HTMLLegendElementImpl.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLLegendElement
- * @see ElementImpl
- */
-public final class HTMLLegendElementImpl
-    extends HTMLElementImpl
-    implements HTMLLegendElement
-{
-
-    
-    public String getAccessKey()
-    {
-        String    accessKey;
-        
-        // Make sure that the access key is a single character.
-        accessKey = getAttribute( "accesskey" );
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        return accessKey;
-    }
-    
-    
-    public void setAccessKey( String accessKey )
-    {
-        // Make sure that the access key is a single character.
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        setAttribute( "accesskey", accessKey );
-    }
-
-    
-    public String getAlign()
-    {
-        return getAttribute( "align" );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-  
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLLegendElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLLinkElementImpl.java b/src/org/apache/html/dom/HTMLLinkElementImpl.java
deleted file mode 100755
index 1c2b7b9..0000000
--- a/src/org/apache/html/dom/HTMLLinkElementImpl.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLLinkElement
- * @see ElementImpl
- */
-public final class HTMLLinkElementImpl
-    extends HTMLElementImpl
-    implements HTMLLinkElement
-{
-
-    
-    public boolean getDisabled()
-    {
-        return getBinary( "disabled" );
-    }
-    
-    
-    public void setDisabled( boolean disabled )
-    {
-        setAttribute( "disabled", disabled );
-    }
-
-    
-    public String getCharset()
-    {
-        return getAttribute( "charset" );
-    }
-    
-    
-    public void setCharset( String charset )
-    {
-        setAttribute( "charset", charset );
-    }
-    
-    
-    public String getHref()
-    {
-        return getAttribute( "href" );
-    }
-    
-    
-    public void setHref( String href )
-    {
-        setAttribute( "href", href );
-    }
-    
-    
-    public String getHreflang()
-    {
-        return getAttribute( "hreflang" );
-    }
-    
-    
-    public void setHreflang( String hreflang )
-    {
-        setAttribute( "hreflang", hreflang );
-    }
-
-    
-    public String getMedia()
-    {
-        return getAttribute( "media" );
-    }
-    
-    
-    public void setMedia( String media )
-    {
-        setAttribute( "media", media );
-    }
-
-  
-    public String getRel()
-    {
-        return getAttribute( "rel" );
-    }
-    
-    
-    public void setRel( String rel )
-    {
-        setAttribute( "rel", rel );
-    }
-    
-    
-    public String getRev()
-    {
-        return getAttribute( "rev" );
-    }
-    
-    
-    public void setRev( String rev )
-    {
-        setAttribute( "rev", rev );
-    }
-
-    
-    public String getTarget()
-    {
-        return getAttribute( "target" );
-    }
-    
-    
-    public void setTarget( String target )
-    {
-        setAttribute( "target", target );
-    }
-  
-  
-    public String getType()
-    {
-        return getAttribute( "type" );
-    }
-    
-    
-    public void setType( String type )
-    {
-        setAttribute( "type", type );
-    }
-    
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLLinkElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLMapElementImpl.java b/src/org/apache/html/dom/HTMLMapElementImpl.java
deleted file mode 100755
index e8c5048..0000000
--- a/src/org/apache/html/dom/HTMLMapElementImpl.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLMapElement
- * @see ElementImpl
- */
-public final class HTMLMapElementImpl
-    extends HTMLElementImpl
-    implements HTMLMapElement
-{
-
-    
-    
-    public HTMLCollection getAreas()
-    {
-        if ( _areas == null )
-            _areas = new HTMLCollectionImpl( this, HTMLCollectionImpl.AREA );
-        return _areas;
-    }
-    
-  
-      public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLMapElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-    
-    
-    private HTMLCollection    _areas;
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLMenuElementImpl.java b/src/org/apache/html/dom/HTMLMenuElementImpl.java
deleted file mode 100755
index 79ebe1a..0000000
--- a/src/org/apache/html/dom/HTMLMenuElementImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLMenuElement
- * @see ElementImpl
- */
-public final class HTMLMenuElementImpl
-    extends HTMLElementImpl
-    implements HTMLMenuElement
-{
-
-    
-    public boolean getCompact()
-    {
-        return getBinary( "compact" );
-    }
-    
-    
-    public void setCompact( boolean compact )
-    {
-        setAttribute( "compact", compact );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLMenuElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLMetaElementImpl.java b/src/org/apache/html/dom/HTMLMetaElementImpl.java
deleted file mode 100755
index 74642a3..0000000
--- a/src/org/apache/html/dom/HTMLMetaElementImpl.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLMetaElement
- * @see ElementImpl
- */
-public final class HTMLMetaElementImpl
-    extends HTMLElementImpl
-    implements HTMLMetaElement
-{
-
-    
-    public String getContent()
-    {
-        return getAttribute( "content" );
-    }
-    
-    
-    public void setContent( String content )
-    {
-        setAttribute( "content", content );
-    }
-
-    
-    
-      public String getHttpEquiv()
-    {
-        return getAttribute( "http-equiv" );
-    }
-    
-    
-    public void setHttpEquiv( String httpEquiv )
-    {
-        setAttribute( "http-equiv", httpEquiv );
-    }
-
-  
-      public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-
-    
-      public String getScheme()
-    {
-        return getAttribute( "scheme" );
-    }
-    
-    
-    public void setScheme( String scheme )
-    {
-        setAttribute( "scheme", scheme );
-    }
-    
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLMetaElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLModElementImpl.java b/src/org/apache/html/dom/HTMLModElementImpl.java
deleted file mode 100755
index 9e97b9d..0000000
--- a/src/org/apache/html/dom/HTMLModElementImpl.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLModElement
- * @see ElementImpl
- */
-public final class HTMLModElementImpl
-    extends HTMLElementImpl
-    implements HTMLModElement
-{
-
-    
-    
-    public String getCite()
-    {
-        return getAttribute( "cite" );
-    }
-    
-    
-    public void setCite( String cite )
-    {
-        setAttribute( "cite", cite );
-    }
-    
-    
-      public String getDateTime()
-    {
-        return getAttribute( "datetime" );
-    }
-    
-    
-    public void setDateTime( String dateTime )
-    {
-        setAttribute( "datetime", dateTime );
-    }
-    
-
-    /**
-     * Constructor requires owner document and tag name.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLModElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLOListElementImpl.java b/src/org/apache/html/dom/HTMLOListElementImpl.java
deleted file mode 100755
index 9f6a73b..0000000
--- a/src/org/apache/html/dom/HTMLOListElementImpl.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLOListElement
- * @see ElementImpl
- */
-public final class HTMLOListElementImpl
-    extends HTMLElementImpl
-    implements HTMLOListElement
-{
-
-    
-    public boolean getCompact()
-    {
-        return getBinary( "compact" );
-    }
-    
-    
-    public void setCompact( boolean compact )
-    {
-        setAttribute( "compact", compact );
-    }
-    
-    
-      public int getStart()
-    {
-        return getInteger( getAttribute( "start" ) );
-    }
-    
-    
-    public void setStart( int start )
-    {
-        setAttribute( "start", String.valueOf( start ) );
-    }
-  
-  
-    public String getType()
-    {
-        return getAttribute( "type" );
-    }
-    
-    
-    public void setType( String type )
-    {
-        setAttribute( "type", type );
-    }
-        
-        
-      /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLOListElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLObjectElementImpl.java b/src/org/apache/html/dom/HTMLObjectElementImpl.java
deleted file mode 100755
index 3fcad9c..0000000
--- a/src/org/apache/html/dom/HTMLObjectElementImpl.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLObjectElement
- * @see ElementImpl
- */
-public final class HTMLObjectElementImpl
-    extends HTMLElementImpl
-    implements HTMLObjectElement, HTMLFormControl
-{
-    
-    
-
-    public String getCode()
-    {
-        return getAttribute( "code" );
-    }
-    
-    
-    public void setCode( String code )
-    {
-        setAttribute( "code", code );
-    }
-
-  
-    public String getAlign()
-    {
-        return capitalize( getAttribute( "align" ) );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-  
-    
-    public String getArchive()
-    {
-        return getAttribute( "archive" );
-    }
-    
-    
-    public void setArchive( String archive )
-    {
-        setAttribute( "archive", archive );
-    }
-    
-    public String getBorder()
-    {
-        return getAttribute( "border" );
-    }
-    
-    
-    public void setBorder( String border )
-    {
-        setAttribute( "border", border );
-    }
-
-    
-    public String getCodeBase()
-    {
-        return getAttribute( "codebase" );
-    }
-    
-    
-    public void setCodeBase( String codeBase )
-    {
-        setAttribute( "codebase", codeBase );
-    }
-
-    
-    public String getCodeType()
-    {
-        return getAttribute( "codetype" );
-    }
-    
-    
-    public void setCodeType( String codeType )
-    {
-        setAttribute( "codetype", codeType );
-    }
-
-    
-    public String getData()
-    {
-        return getAttribute( "data" );
-    }
-    
-    
-    public void setData( String data )
-    {
-        setAttribute( "data", data );
-    }
-
-  
-      public boolean getDeclare()
-    {
-        return getBinary( "declare" );
-    }
-    
-    
-    public void setDeclare( boolean declare )
-    {
-        setAttribute( "declare", declare );
-    }
-
-    
-    public String getHeight()
-    {
-        return getAttribute( "height" );
-    }
-    
-    
-    public void setHeight( String height )
-    {
-        setAttribute( "height", height );
-    }
-
-    
-    public String getHspace()
-    {
-        return getAttribute( "hspace" );
-    }
-    
-    
-    public void setHspace( String hspace )
-    {
-        setAttribute( "hspace", hspace );
-    }
-  
-    public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-
-    
-    public String getStandby()
-    {
-        return getAttribute( "standby" );
-    }
-    
-    
-    public void setStandby( String standby )
-    {
-        setAttribute( "standby", standby );
-    }
-  
-      public int getTabIndex()
-    {
-        try
-        {
-            return Integer.parseInt( getAttribute( "tabindex" ) );
-        }
-        catch ( NumberFormatException except )
-        {
-            return 0;
-        }
-    }
-    
-    
-    public void setTabIndex( int tabIndex )
-    {
-        setAttribute( "tabindex", String.valueOf( tabIndex ) );
-    }
-
-    
-    public String getType()
-    {
-        return getAttribute( "type" );
-    }
-    
-    
-    public void setType( String type )
-    {
-        setAttribute( "type", type );
-    }
-    
-    
-    public String getUseMap()
-    {
-        return getAttribute( "useMap" );
-    }
-    
-    
-    public void setUseMap( String useMap )
-    {
-        setAttribute( "useMap", useMap );
-    }
-    
-    
-    public String getVspace()
-    {
-        return getAttribute( "vspace" );
-    }
-    
-    
-    public void setVspace( String vspace )
-    {
-        setAttribute( "vspace", vspace );
-    }
-
-  
-    public String getWidth()
-    {
-        return getAttribute( "width" );
-    }
-    
-    
-    public void setWidth( String width )
-    {
-        setAttribute( "width", width );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLObjectElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLOptGroupElementImpl.java b/src/org/apache/html/dom/HTMLOptGroupElementImpl.java
deleted file mode 100755
index e032b36..0000000
--- a/src/org/apache/html/dom/HTMLOptGroupElementImpl.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLOptGroupElement
- * @see ElementImpl
- */
-public final class HTMLOptGroupElementImpl
-    extends HTMLElementImpl
-    implements HTMLOptGroupElement
-{
-
-        
-    public boolean getDisabled()
-    {
-        return getBinary( "disabled" );
-    }
-    
-    
-    public void setDisabled( boolean disabled )
-    {
-        setAttribute( "disabled", disabled );
-    }
-
-    
-      public String getLabel()
-    {
-        return capitalize( getAttribute( "label" ) );
-    }
-    
-    
-    public void setLabel( String label )
-    {
-        setAttribute( "label", label );
-    }
-
-    
-      /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLOptGroupElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLOptionElementImpl.java b/src/org/apache/html/dom/HTMLOptionElementImpl.java
deleted file mode 100755
index 52eafe8..0000000
--- a/src/org/apache/html/dom/HTMLOptionElementImpl.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@openxml.org">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLOptionElement
- * @see ElementImpl
- */
-public final class HTMLOptionElementImpl
-    extends HTMLElementImpl
-    implements HTMLOptionElement
-{
-
-    
-
-    public boolean getDefaultSelected()
-    {
-        // ! NOT FULLY IMPLEMENTED !
-        return getBinary( "default-selected" );
-    }
-    
-    
-    public void setDefaultSelected( boolean defaultSelected )
-    {
-        // ! NOT FULLY IMPLEMENTED !
-        setAttribute( "default-selected", defaultSelected );
-    }
-
-  
-    public String getText()
-    {
-        Node    child;
-        String    text;
-        
-        // Find the Text nodes contained within this element and return their
-        // concatenated value. Required to go around comments, entities, etc.
-        child = getFirstChild();
-        text = "";
-        while ( child != null )
-        {
-            if ( child instanceof Text )
-                text = text + ( (Text) child ).getData();
-            child = child.getNextSibling();
-        }
-        return text;
-    }
-    
-    
-    public void setText( String text )
-    {
-        Node    child;
-        Node    next;
-        
-        // Delete all the nodes and replace them with a single Text node.
-        // This is the only approach that can handle comments and other nodes.
-        child = getFirstChild();
-        while ( child != null )
-        {
-            next = child.getNextSibling();
-            removeChild( child );
-            child = next;
-        }
-        insertBefore( getOwnerDocument().createTextNode( text ), getFirstChild() );
-    }
-    
-    
-    public int getIndex()
-    {
-        Node        parent;
-        NodeList    options;
-        int            i;
-        
-        // Locate the parent SELECT. Note that this OPTION might be inside a
-        // OPTGROUP inside the SELECT. Or it might not have a parent SELECT.
-        // Everything is possible. If no parent is found, return -1.
-        parent = getParentNode();
-        while ( parent != null && ! ( parent instanceof HTMLSelectElement ) )
-            parent = parent.getParentNode();
-        if ( parent != null )
-        {
-            // Use getElementsByTagName() which creates a snapshot of all the
-            // OPTION elements under the SELECT. Access to the returned NodeList
-            // is very fast and the snapshot solves many synchronization problems.
-            options = ( (HTMLElement) parent ).getElementsByTagName( "OPTION" );
-            for ( i = 0 ; i < options.getLength() ; ++i )
-                if ( options.item( i ) == this )
-                    return i;
-        }
-        return -1;
-    }
-    
-    
-    public void setIndex( int index )
-    {
-        Node        parent;
-        NodeList    options;
-        Node        item;
-        
-        // Locate the parent SELECT. Note that this OPTION might be inside a
-        // OPTGROUP inside the SELECT. Or it might not have a parent SELECT.
-        // Everything is possible. If no parent is found, just return.
-        parent = getParentNode();
-        while ( parent != null && ! ( parent instanceof HTMLSelectElement ) )
-            parent = parent.getParentNode();
-        if ( parent != null )
-        {
-            // Use getElementsByTagName() which creates a snapshot of all the
-            // OPTION elements under the SELECT. Access to the returned NodeList
-            // is very fast and the snapshot solves many synchronization problems.
-            // Make sure this OPTION is not replacing itself.
-            options = ( (HTMLElement) parent ).getElementsByTagName( "OPTION" );
-            if ( options.item( index ) != this )
-            {
-                // Remove this OPTION from its parent. Place this OPTION right
-                // before indexed OPTION underneath it's direct parent (might
-                // be an OPTGROUP).
-                getParentNode().removeChild( this );
-                item = options.item( index );
-                item.getParentNode().insertBefore( this, item );
-            }
-        }
-    }
-  
-  
-    public boolean getDisabled()
-    {
-        return getBinary( "disabled" );
-    }
-    
-    
-    public void setDisabled( boolean disabled )
-    {
-        setAttribute( "disabled", disabled );
-    }
-
-    
-      public String getLabel()
-    {
-        return capitalize( getAttribute( "label" ) );
-    }
-    
-    
-    public void setLabel( String label )
-    {
-        setAttribute( "label", label );
-    }
-
-    
-    public boolean getSelected()
-    {
-        return getBinary( "selected" );
-    }
-  
-  
-    public void setSelected( boolean selected )
-    {
-        setAttribute( "selected", selected );
-    }
-    
-        
-    public String getValue()
-    {
-        return getAttribute( "value" );
-    }
-    
-    
-    public void setValue( String value )
-    {
-        setAttribute( "value", value );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLOptionElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLParagraphElementImpl.java b/src/org/apache/html/dom/HTMLParagraphElementImpl.java
deleted file mode 100755
index 26cb1de..0000000
--- a/src/org/apache/html/dom/HTMLParagraphElementImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLParagraphElement
- * @see ElementImpl
- */
-public final class HTMLParagraphElementImpl
-    extends HTMLElementImpl
-    implements HTMLParagraphElement
-{
-    
-    
-    public String getAlign()
-    {
-        return getAttribute( "align" );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-  
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLParagraphElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLParamElementImpl.java b/src/org/apache/html/dom/HTMLParamElementImpl.java
deleted file mode 100755
index 5bf5d93..0000000
--- a/src/org/apache/html/dom/HTMLParamElementImpl.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLParamElement
- * @see ElementImpl
- */
-public final class HTMLParamElementImpl
-    extends HTMLElementImpl
-    implements HTMLParamElement
-{
-    
-    
-    public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-  
-  
-    public String getType()
-    {
-        return getAttribute( "type" );
-    }
-    
-    
-    public void setType( String type )
-    {
-        setAttribute( "type", type );
-    }
-    
-    
-      public String getValue()
-    {
-        return getAttribute( "value" );
-    }
-    
-    
-    public void setValue( String value )
-    {
-        setAttribute( "value", value );
-    }
-
-    
-      public String getValueType()
-    {
-        return capitalize( getAttribute( "valuetype" ) );
-    }
-    
-    
-    public void setValueType( String valueType )
-    {
-        setAttribute( "valuetype", valueType );
-    }
-
-
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLParamElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLPreElementImpl.java b/src/org/apache/html/dom/HTMLPreElementImpl.java
deleted file mode 100755
index b261029..0000000
--- a/src/org/apache/html/dom/HTMLPreElementImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLPreElement
- * @see ElementImpl
- */
-public final class HTMLPreElementImpl
-    extends HTMLElementImpl
-    implements HTMLPreElement
-{
-    
-    
-      public int getWidth()
-    {
-        return getInteger( getAttribute( "width" ) );
-    }
-    
-    
-    public void setWidth( int width )
-    {
-        setAttribute( "width", String.valueOf( width ) );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLPreElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLQuoteElementImpl.java b/src/org/apache/html/dom/HTMLQuoteElementImpl.java
deleted file mode 100755
index 5169ea7..0000000
--- a/src/org/apache/html/dom/HTMLQuoteElementImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLQuoteElement
- * @see ElementImpl
- */
-public final class HTMLQuoteElementImpl
-    extends HTMLElementImpl
-    implements HTMLQuoteElement
-{
-    
-    
-    public String getCite()
-    {
-        return getAttribute( "cite" );
-    }
-    
-    
-    public void setCite( String cite )
-    {
-        setAttribute( "cite", cite );
-    }
-    
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLQuoteElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLScriptElementImpl.java b/src/org/apache/html/dom/HTMLScriptElementImpl.java
deleted file mode 100755
index d97a713..0000000
--- a/src/org/apache/html/dom/HTMLScriptElementImpl.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLScriptElement
- * @see ElementImpl
- */
-public final class HTMLScriptElementImpl
-    extends HTMLElementImpl
-    implements HTMLScriptElement
-{
-    
-    
-    public String getText()
-    {
-        Node    child;
-        String    text;
-        
-        // Find the Text nodes contained within this element and return their
-        // concatenated value. Required to go around comments, entities, etc.
-        child = getFirstChild();
-        text = "";
-        while ( child != null )
-        {
-            if ( child instanceof Text )
-                text = text + ( (Text) child ).getData();
-            child = child.getNextSibling();
-        }
-        return text;
-    }
-    
-    
-    public void setText( String text )
-    {
-        Node    child;
-        Node    next;
-        
-        // Delete all the nodes and replace them with a single Text node.
-        // This is the only approach that can handle comments and other nodes.
-        child = getFirstChild();
-        while ( child != null )
-        {
-            next = child.getNextSibling();
-            removeChild( child );
-            child = next;
-        }
-        insertBefore( getOwnerDocument().createTextNode( text ), getFirstChild() );
-    }
-
-    
-       public String getHtmlFor()
-    {
-        return getAttribute( "for" );
-    }
-    
-    
-    public void setHtmlFor( String htmlFor )
-    {
-        setAttribute( "for", htmlFor );
-    }
-
-    
-       public String getEvent()
-    {
-        return getAttribute( "event" );
-    }
-    
-    
-    public void setEvent( String event )
-    {
-        setAttribute( "event", event );
-    }
-    
-       public String getCharset()
-    {
-        return getAttribute( "charset" );
-    }
-    
-    
-    public void setCharset( String charset )
-    {
-        setAttribute( "charset", charset );
-    }
-
-    
-    public boolean getDefer()
-    {
-        return getBinary( "defer" );
-    }
-    
-    
-    public void setDefer( boolean defer )
-    {
-        setAttribute( "defer", defer );
-    }
-
-  
-       public String getSrc()
-    {
-        return getAttribute( "src" );
-    }
-    
-    
-    public void setSrc( String src )
-    {
-        setAttribute( "src", src );
-    }
-
-  
-    public String getType()
-    {
-        return getAttribute( "type" );
-    }
-    
-    
-    public void setType( String type )
-    {
-        setAttribute( "type", type );
-    }
-    
-    
-      /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLScriptElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLSelectElementImpl.java b/src/org/apache/html/dom/HTMLSelectElementImpl.java
deleted file mode 100755
index ba5981a..0000000
--- a/src/org/apache/html/dom/HTMLSelectElementImpl.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLSelectElement
- * @see ElementImpl
- */
-public final class HTMLSelectElementImpl
-    extends HTMLElementImpl
-    implements HTMLSelectElement, HTMLFormControl
-{
-    
-    
-    public String getType()
-    {
-        return getAttribute( "type" );
-    }
-
-    
-      public String getValue()
-    {
-        return getAttribute( "value" );
-    }
-    
-    
-    public void setValue( String value )
-    {
-        setAttribute( "value", value );
-    }
-
-    
-    public int getSelectedIndex()
-    {
-        NodeList    options;
-        int            i;
-        
-        // Use getElementsByTagName() which creates a snapshot of all the
-        // OPTION elements under this SELECT. Access to the returned NodeList
-        // is very fast and the snapshot solves many synchronization problems.
-        // Locate the first selected OPTION and return its index. Note that
-        // the OPTION might be under an OPTGROUP.
-        options = getElementsByTagName( "OPTION" );
-        for ( i = 0 ; i < options.getLength() ; ++i )
-            if ( ( (HTMLOptionElement) options.item( i ) ).getSelected() )
-                return i;
-        return -1;
-    }
-    
-    
-    public void setSelectedIndex( int selectedIndex )
-    {
-        NodeList    options;
-        int            i;
-        
-        // Use getElementsByTagName() which creates a snapshot of all the
-        // OPTION elements under this SELECT. Access to the returned NodeList
-        // is very fast and the snapshot solves many synchronization problems.
-        // Change the select so all OPTIONs are off, except for the
-        // selectIndex-th one.
-        options = getElementsByTagName( "OPTION" );
-        for ( i = 0 ; i < options.getLength() ; ++i )
-            ( (HTMLOptionElementImpl) options.item( i ) ).setSelected( i == selectedIndex );
-    }
-
-  
-    public HTMLCollection getOptions()
-    {
-        if ( _options == null )
-            _options = new HTMLCollectionImpl( this, HTMLCollectionImpl.OPTION );
-        return _options;
-    }
-    
-
-    public int getLength()
-    {
-        return getOptions().getLength();
-    }
-    
-    
-    public boolean getDisabled()
-    {
-        return getBinary( "disabled" );
-    }
-    
-    
-    public void setDisabled( boolean disabled )
-    {
-        setAttribute( "disabled", disabled );
-    }
-
-    
-      public boolean getMultiple()
-    {
-        return getBinary( "multiple" );
-    }
-    
-    
-    public void setMultiple( boolean multiple )
-    {
-        setAttribute( "multiple", multiple );
-    }
-
-  
-      public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-
-    
-    public int getSize()
-    {
-        return getInteger( getAttribute( "size" ) );
-    }
-    
-    
-    public void setSize( int size )
-    {
-        setAttribute( "size", String.valueOf( size ) );
-    }
-
-  
-    public int getTabIndex()
-    {
-        return getInteger( getAttribute( "tabindex" ) );
-    }
-    
-    
-    public void setTabIndex( int tabIndex )
-    {
-        setAttribute( "tabindex", String.valueOf( tabIndex ) );
-    }
-
-    
-    public void add( HTMLElement element, HTMLElement before )
-    {
-        insertBefore( element, before );
-    }
-  
-  
-    public void remove( int index )
-    {
-        NodeList    options;
-        Node        removed;
-        
-        // Use getElementsByTagName() which creates a snapshot of all the
-        // OPTION elements under this SELECT. Access to the returned NodeList
-        // is very fast and the snapshot solves many synchronization problems.
-        // Remove the indexed OPTION from it's parent, this might be this
-        // SELECT or an OPTGROUP.
-        options = getElementsByTagName( "OPTION" );
-        removed = options.item( index );
-        if ( removed != null )
-            removed.getParentNode().removeChild ( removed );
-    }
-
-  
-    public void               blur()
-    {
-        // No scripting in server-side DOM. This method is moot.
-    }
-      
-      
-    public void               focus()
-    {
-        // No scripting in server-side DOM. This method is moot.
-    }
-
-  
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLSelectElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-
-    private HTMLCollection    _options;
-  
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLStyleElementImpl.java b/src/org/apache/html/dom/HTMLStyleElementImpl.java
deleted file mode 100755
index d4eb850..0000000
--- a/src/org/apache/html/dom/HTMLStyleElementImpl.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLStyleElement
- * @see ElementImpl
- */
-public final class HTMLStyleElementImpl
-    extends HTMLElementImpl
-    implements HTMLStyleElement
-{
-    
-    
-    public boolean getDisabled()
-    {
-        return getBinary( "disabled" );
-    }
-    
-    
-    public void setDisabled( boolean disabled )
-    {
-        setAttribute( "disabled", disabled );
-    }
-
-    
-    public String getMedia()
-    {
-        return getAttribute( "media" );
-    }
-    
-    
-    public void setMedia( String media )
-    {
-        setAttribute( "media", media );
-    }
-  
-  
-    public String getType()
-    {
-        return getAttribute( "type" );
-    }
-    
-    
-    public void setType( String type )
-    {
-        setAttribute( "type", type );
-    }
-    
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLStyleElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLTableCaptionElementImpl.java b/src/org/apache/html/dom/HTMLTableCaptionElementImpl.java
deleted file mode 100755
index 045b5b8..0000000
--- a/src/org/apache/html/dom/HTMLTableCaptionElementImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLTableCaptionElement
- * @see ElementImpl
- */
-public final class HTMLTableCaptionElementImpl
-    extends HTMLElementImpl
-    implements HTMLTableCaptionElement
-{
-    
-    
-    public String getAlign()
-    {
-        return getAttribute( "align" );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-  
-    
-      /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLTableCaptionElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLTableCellElementImpl.java b/src/org/apache/html/dom/HTMLTableCellElementImpl.java
deleted file mode 100755
index 0b928a9..0000000
--- a/src/org/apache/html/dom/HTMLTableCellElementImpl.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLTableCellElement
- * @see ElementImpl
- */
-public final class HTMLTableCellElementImpl
-    extends HTMLElementImpl
-    implements HTMLTableCellElement
-{
-    
-
-    public int getCellIndex()
-    {
-        Node    parent;
-        Node    child;
-        int        index;
-        
-        parent = getParentNode();
-        index = 0;
-        if ( parent instanceof HTMLTableRowElement )
-        {
-            child = parent.getFirstChild();
-            while ( child != null )
-            {
-                if ( child instanceof HTMLTableCellElement )
-                {
-                    if ( child == this )
-                        return index;
-                    ++ index;
-                }
-                child = child.getNextSibling();
-            }
-        }
-        return -1;
-    }
-    
-    
-    public void setCellIndex( int cellIndex )
-    {
-        Node    parent;
-        Node    child;
-        int        index;
-        
-        parent = getParentNode();
-        if ( parent instanceof HTMLTableRowElement )
-        {
-            child = parent.getFirstChild();
-            while ( child != null )
-            {
-                if ( child instanceof HTMLTableCellElement )
-                {
-                    if ( cellIndex == 0 )
-                    {
-                        if ( this != child )
-                            parent.insertBefore( this, child );
-                        return;
-                    }
-                    -- cellIndex;
-                }
-                child = child.getNextSibling();
-            }
-        }
-        parent.appendChild( this );
-    }
-
-  
-    public String getAbbr()
-    {
-        return getAttribute( "abbr" );
-    }
-    
-    
-    public void setAbbr( String abbr )
-    {
-        setAttribute( "abbr", abbr );
-    }
-
-  
-    public String getAlign()
-    {
-        return capitalize( getAttribute( "align" ) );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-  
-    
-    public String getAxis()
-    {
-        return getAttribute( "axis" );
-    }
-    
-    
-    public void setAxis( String axis )
-    {
-        setAttribute( "axis", axis );
-    }
-    
-    public String getBgColor()
-    {
-        return getAttribute( "bgcolor" );
-    }
-    
-    
-    public void setBgColor( String bgColor )
-    {
-        setAttribute( "bgcolor", bgColor );
-    }
-
-  
-    public String getCh()
-    {
-        String    ch;
-        
-        // Make sure that the access key is a single character.
-        ch = getAttribute( "char" );
-        if ( ch != null && ch.length() > 1 )
-            ch = ch.substring( 0, 1 );
-        return ch;
-    }
-    
-    
-    public void setCh( String ch )
-    {
-        // Make sure that the access key is a single character.
-        if ( ch != null && ch.length() > 1 )
-            ch = ch.substring( 0, 1 );
-        setAttribute( "char", ch );
-    }
-
-    
-    public String getChOff()
-    {
-        return getAttribute( "charoff" );
-    }
-    
-    
-    public void setChOff( String chOff )
-    {
-        setAttribute( "charoff", chOff );
-    }
-  
-  
-    public int getColSpan()
-    {
-        return getInteger( getAttribute( "colspan" ) );
-    }
-    
-    
-    public void setColSpan( int colspan )
-    {
-        setAttribute( "colspan", String.valueOf( colspan ) );
-    }
-    
-    
-    public String getHeaders()
-    {
-        return getAttribute( "headers" );
-    }
-    
-    
-    public void setHeaders( String headers )
-    {
-        setAttribute( "headers", headers );
-    }
-  
-  
-    public String getHeight()
-    {
-        return getAttribute( "height" );
-    }
-    
-    
-    public void setHeight( String height )
-    {
-        setAttribute( "height", height );
-    }
-
-  
-      public boolean getNoWrap()
-    {
-        return getBinary( "nowrap" );
-    }
-    
-    
-    public void setNoWrap( boolean noWrap )
-    {
-        setAttribute( "nowrap", noWrap );
-    }
-
-    public int getRowSpan()
-    {
-        return getInteger( getAttribute( "rowspan" ) );
-    }
-    
-    
-    public void setRowSpan( int rowspan )
-    {
-        setAttribute( "rowspan", String.valueOf( rowspan ) );
-    }
-  
-    
-    public String getScope()
-    {
-        return getAttribute( "scope" );
-    }
-    
-    
-    public void setScope( String scope )
-    {
-        setAttribute( "scope", scope );
-    }
-  
-  
-    public String getVAlign()
-    {
-        return capitalize( getAttribute( "valign" ) );
-    }
-    
-    
-    public void setVAlign( String vAlign )
-    {
-        setAttribute( "valign", vAlign );
-    }
-
-  
-      public String getWidth()
-    {
-        return getAttribute( "width" );
-    }
-    
-    
-    public void setWidth( String width )
-    {
-        setAttribute( "width", width );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLTableCellElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLTableColElementImpl.java b/src/org/apache/html/dom/HTMLTableColElementImpl.java
deleted file mode 100755
index 41fa70b..0000000
--- a/src/org/apache/html/dom/HTMLTableColElementImpl.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLTableColElement
- * @see ElementImpl
- */
-public final class HTMLTableColElementImpl
-    extends HTMLElementImpl
-    implements HTMLTableColElement
-{
-    
-    
-    public String getAlign()
-    {
-        return capitalize( getAttribute( "align" ) );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-  
-    
-    public String getCh()
-    {
-        String    ch;
-        
-        // Make sure that the access key is a single character.
-        ch = getAttribute( "char" );
-        if ( ch != null && ch.length() > 1 )
-            ch = ch.substring( 0, 1 );
-        return ch;
-    }
-    
-    
-    public void setCh( String ch )
-    {
-        // Make sure that the access key is a single character.
-        if ( ch != null && ch.length() > 1 )
-            ch = ch.substring( 0, 1 );
-        setAttribute( "char", ch );
-    }
-
-
-    public String getChOff()
-    {
-        return getAttribute( "charoff" );
-    }
-    
-    
-    public void setChOff( String chOff )
-    {
-        setAttribute( "charoff", chOff );
-    }
-  
-  
-    public int getSpan()
-    {
-        return getInteger( getAttribute( "span" ) );
-    }
-    
-    
-    public void setSpan( int span )
-    {
-        setAttribute( "span", String.valueOf( span ) );
-    }
-
-    
-    public String getVAlign()
-    {
-        return capitalize( getAttribute( "valign" ) );
-    }
-    
-    
-    public void setVAlign( String vAlign )
-    {
-        setAttribute( "valign", vAlign );
-    }
-    
-    public String getWidth()
-    {
-        return getAttribute( "width" );
-    }
-    
-    
-    public void setWidth( String width )
-    {
-        setAttribute( "width", width );
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLTableColElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLTableElementImpl.java b/src/org/apache/html/dom/HTMLTableElementImpl.java
deleted file mode 100755
index 2fe6d8a..0000000
--- a/src/org/apache/html/dom/HTMLTableElementImpl.java
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLAnchorElement
- * @see ElementImpl
- */
-public final class HTMLTableElementImpl
-    extends HTMLElementImpl
-    implements HTMLTableElement
-{
-    
-    
-    public synchronized HTMLTableCaptionElement getCaption()
-    {
-        Node    child;
-        
-        child = getFirstChild();
-        while ( child != null )
-        {
-            if ( child instanceof HTMLTableCaptionElement &&
-                 child.getNodeName().equals( "CAPTION" ) )
-                return (HTMLTableCaptionElement) child;
-            child = child.getNextSibling();
-        }
-        return null;
-    }
-    
-    
-    public synchronized void setCaption( HTMLTableCaptionElement caption )
-    {
-        if ( caption != null && ! caption.getTagName().equals( "CAPTION" ) )
-            throw new IllegalArgumentException( "HTM016 Argument 'caption' is not an element of type <CAPTION>." );
-        deleteCaption();
-        if ( caption != null )
-            appendChild( caption );
-    }
-    
-    
-    public synchronized HTMLElement createCaption()
-    {
-        HTMLElement    section;
-        
-        section = getCaption();
-        if ( section != null )
-            return section;
-        section = new HTMLTableCaptionElementImpl( (HTMLDocumentImpl) getOwnerDocument(), "CAPTION" );
-        appendChild( section );
-        return section;
-    }
-
-  
-    public synchronized void deleteCaption()
-    {
-        Node    old;
-        
-        old = getCaption();
-        if ( old != null )
-            removeChild ( old );
-    }
-    
-    public synchronized HTMLTableSectionElement getTHead()
-    {
-        Node    child;
-        
-        child = getFirstChild();
-        while ( child != null )
-        {
-            if ( child instanceof HTMLTableSectionElement &&
-                 child.getNodeName().equals( "THEAD" ) )
-                return (HTMLTableSectionElement) child;
-            child = child.getNextSibling();
-        }
-        return null;
-    }
-    
-    
-    public synchronized void setTHead( HTMLTableSectionElement tHead )
-    {
-        if ( tHead != null && ! tHead.getTagName().equals( "THEAD" ) )
-            throw new IllegalArgumentException( "HTM017 Argument 'tHead' is not an element of type <THEAD>." );
-        deleteTHead();
-        if ( tHead != null )
-            appendChild( tHead );
-    }
-    
-    
-    public synchronized HTMLElement createTHead()
-    {
-        HTMLElement    section;
-        
-        section = getTHead();
-        if ( section != null )
-            return section;
-        section = new HTMLTableSectionElementImpl( (HTMLDocumentImpl) getOwnerDocument(), "THEAD" );
-        appendChild( section );
-        return section;
-    }
-
-    
-    public synchronized void deleteTHead()
-    {
-        Node    old;
-        
-        old = getTHead();
-        if ( old != null )
-            removeChild ( old );
-    }
-    
-    public synchronized HTMLTableSectionElement getTFoot()
-    {
-        Node    child;
-        
-        child = getFirstChild();
-        while ( child != null )
-        {
-            if ( child instanceof HTMLTableSectionElement &&
-                 child.getNodeName().equals( "TFOOT" ) )
-                return (HTMLTableSectionElement) child;
-            child = child.getNextSibling();
-        }
-        return null;
-    }
-    
-    
-    public synchronized void setTFoot( HTMLTableSectionElement tFoot )
-    {
-        if ( tFoot != null && ! tFoot.getTagName().equals( "TFOOT" ) )
-            throw new IllegalArgumentException( "HTM018 Argument 'tFoot' is not an element of type <TFOOT>." );
-        deleteTFoot();
-        if ( tFoot != null )
-            appendChild( tFoot );
-    }
-    
-    
-    public synchronized HTMLElement createTFoot()
-    {
-        HTMLElement    section;
-        
-        section = getTFoot();
-        if ( section != null )
-            return section;
-        section = new HTMLTableSectionElementImpl( (HTMLDocumentImpl) getOwnerDocument(), "TFOOT" );
-        appendChild( section );
-        return section;
-    }
-
-    
-    public synchronized void deleteTFoot()
-    {
-        Node    old;
-        
-        old = getTFoot();
-        if ( old != null )
-            removeChild ( old );
-    }
-    
-    public HTMLCollection getRows()
-    {
-        if ( _rows == null )
-            _rows = new HTMLCollectionImpl( this, HTMLCollectionImpl.ROW );
-        return _rows;
-    }
-    
-
-    public HTMLCollection getTBodies()
-    {
-        if ( _bodies == null )
-            _bodies = new HTMLCollectionImpl( this, HTMLCollectionImpl.TBODY );
-        return _bodies;
-    }
-  
-  
-    public String getAlign()
-    {
-        return capitalize( getAttribute( "align" ) );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-  
-    
-    public String getBgColor()
-    {
-        return getAttribute( "bgcolor" );
-    }
-    
-    
-    public void setBgColor( String bgColor )
-    {
-        setAttribute( "bgcolor", bgColor );
-    }
-  
-  
-    public String getBorder()
-    {
-        return getAttribute( "border" );
-    }
-    
-    
-    public void setBorder( String border )
-    {
-        setAttribute( "border", border );
-    }
-
-    
-    public String getCellPadding()
-    {
-        return getAttribute( "cellpadding" );
-    }
-    
-    
-    public void setCellPadding( String cellPadding )
-    {
-        setAttribute( "cellpadding", cellPadding );
-    }
-    
-    
-    public String getCellSpacing()
-    {
-        return getAttribute( "cellspacing" );
-    }
-    
-    
-    public void setCellSpacing( String cellSpacing )
-    {
-        setAttribute( "cellspacing", cellSpacing );
-    }
-    
-    
-    public String getFrame()
-    {
-        return capitalize( getAttribute( "frame" ) );
-    }
-    
-    
-    public void setFrame( String frame )
-    {
-        setAttribute( "frame", frame );
-    }
-    
-    
-    public String getRules()
-    {
-        return capitalize( getAttribute( "rules" ) );
-    }
-    
-    
-    public void setRules( String rules )
-    {
-        setAttribute( "rules", rules );
-    }
-    
-    
-    public String getSummary()
-    {
-        return getAttribute( "summary" );
-    }
-    
-    
-    public void setSummary( String summary )
-    {
-        setAttribute( "summary", summary );
-    }
-
-  
-      public String getWidth()
-    {
-        return getAttribute( "width" );
-    }
-    
-    
-    public void setWidth( String width )
-    {
-        setAttribute( "width", width );
-    }
-
-    
-    public HTMLElement insertRow( int index )
-    {
-        HTMLTableRowElementImpl    newRow;
-
-        newRow = new HTMLTableRowElementImpl( (HTMLDocumentImpl) getOwnerDocument(), "TR" );
-        //newRow.insertCell( 0 );
-        insertRowX( index, newRow );
-        return newRow;
-    }
-        
-        
-    void insertRowX( int index, HTMLTableRowElementImpl newRow )
-    {
-        Node    child;
-        Node    lastSection = null;
-                
-        child = getFirstChild();
-        while ( child != null )
-        {
-            if ( child instanceof HTMLTableRowElement )
-            {
-                if ( index == 0 )
-                {
-                    insertBefore( newRow, child );
-                    return;
-                }
-            }
-            else
-            if ( child instanceof HTMLTableSectionElementImpl )
-            {
-                lastSection = child;
-                index = ( (HTMLTableSectionElementImpl) child ).insertRowX( index, newRow );
-                if ( index < 0 )
-                    return;
-            }
-            child = child.getNextSibling();
-        }
-        if ( lastSection != null )
-            lastSection.appendChild( newRow );
-        else
-            appendChild( newRow );
-    }
-    
-    
-    public synchronized void deleteRow( int index )
-    {
-        Node    child;
-        
-        child = getFirstChild();
-        while ( child != null )
-        {
-            if ( child instanceof HTMLTableRowElement )
-            {
-                if ( index == 0 )
-                {
-                    removeChild ( child );
-                    return;
-                }
-            }
-            else
-            if ( child instanceof HTMLTableSectionElementImpl )
-            {
-                index = ( (HTMLTableSectionElementImpl) child ).deleteRowX( index );
-                if ( index < 0 )
-                    return;
-            }
-            child = child.getNextSibling();
-        }
-    }
-
-  
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLTableElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-    
-  
-    private HTMLCollectionImpl    _rows;
-    
-    
-    private HTMLCollectionImpl    _bodies;
-  
-    
-}
-
diff --git a/src/org/apache/html/dom/HTMLTableRowElementImpl.java b/src/org/apache/html/dom/HTMLTableRowElementImpl.java
deleted file mode 100755
index 3732ca8..0000000
--- a/src/org/apache/html/dom/HTMLTableRowElementImpl.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLTableRowElement
- * @see ElementImpl
- */
-public final class HTMLTableRowElementImpl
-    extends HTMLElementImpl
-    implements HTMLTableRowElement
-{
-
-    
-    public int getRowIndex()
-    {
-        Node    parent;
-        
-        parent = getParentNode();
-        if ( parent instanceof HTMLTableSectionElement )
-            parent = parent.getParentNode();
-        if ( parent instanceof HTMLTableElement )
-            return getRowIndex( parent );;
-        return -1;
-    }
-    
-    
-    public void setRowIndex( int rowIndex )
-    {
-        Node    parent;
-        
-        parent = getParentNode();
-        if ( parent instanceof HTMLTableSectionElement )
-            parent = parent.getParentNode();
-        if ( parent instanceof HTMLTableElement )
-            ( (HTMLTableElementImpl) parent ).insertRowX( rowIndex, this );
-    }
-
-  
-    public int getSectionRowIndex()
-    {
-        Node    parent;
-        
-        parent = getParentNode();
-        if ( parent instanceof HTMLTableSectionElement )
-            return getRowIndex( parent );
-        else
-            return -1;
-    }
-    
-    
-    public void setSectionRowIndex( int sectionRowIndex )
-    {
-        Node    parent;
-        
-        parent = getParentNode();
-        if ( parent instanceof HTMLTableSectionElement )
-            ( (HTMLTableSectionElementImpl) parent ).insertRowX( sectionRowIndex, this );
-    }
-  
-  
-    int getRowIndex( Node parent )
-    {
-        NodeList    rows;
-        int            i;
-        
-        // Use getElementsByTagName() which creates a snapshot of all the
-        // TR elements under the TABLE/section. Access to the returned NodeList
-        // is very fast and the snapshot solves many synchronization problems.
-        rows = ( (HTMLElement) parent ).getElementsByTagName( "TR" );
-        for ( i = 0 ; i < rows.getLength() ; ++i )
-            if ( rows.item( i ) == this )
-                return i;
-        return -1;
-    }
-
-  
-    public HTMLCollection  getCells()
-    {
-        if ( _cells == null )
-            _cells = new HTMLCollectionImpl( this, HTMLCollectionImpl.CELL );
-        return _cells;
-    }
-    
-    
-    public void setCells( HTMLCollection cells )
-    {
-        Node    child;
-        int        i;
-        
-        child = getFirstChild();
-        while ( child != null )
-        {
-            removeChild( child );
-            child = child.getNextSibling();
-        }
-        i = 0;
-        child = cells.item( i );
-        while ( child != null )
-        {
-            appendChild ( child );
-            ++i;
-            child = cells.item( i );
-        }
-    }
-
-  
-    public HTMLElement insertCell( int index )
-    {
-        Node        child;
-        HTMLElement    newCell;
-        
-        newCell = new HTMLTableCellElementImpl( (HTMLDocumentImpl) getOwnerDocument(), "TD" );
-        child = getFirstChild();
-        while ( child != null )
-        {
-            if ( child instanceof HTMLTableCellElement )
-            {
-                if ( index == 0 )
-                {
-                    insertBefore( newCell, child );
-                    return newCell;
-                }
-                --index;
-            }
-            child = child.getNextSibling();
-        }
-        appendChild( newCell );
-        return newCell;
-    }
-    
-    
-    public void deleteCell( int index )
-    {
-        Node    child;
-        
-        child = getFirstChild();
-        while ( child != null )
-        {
-            if ( child instanceof HTMLTableCellElement )
-            {
-                if ( index == 0 )
-                {
-                    removeChild ( child );
-                    return;
-                }
-                --index;
-            }
-            child = child.getNextSibling();
-        }
-    }
-
-  
-    public String getAlign()
-    {
-        return capitalize( getAttribute( "align" ) );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-
-    
-    public String getBgColor()
-    {
-        return getAttribute( "bgcolor" );
-    }
-    
-    
-    public void setBgColor( String bgColor )
-    {
-        setAttribute( "bgcolor", bgColor );
-    }
-
-  
-    public String getCh()
-    {
-        String    ch;
-        
-        // Make sure that the access key is a single character.
-        ch = getAttribute( "char" );
-        if ( ch != null && ch.length() > 1 )
-            ch = ch.substring( 0, 1 );
-        return ch;
-    }
-    
-    
-    public void setCh( String ch )
-    {
-        // Make sure that the access key is a single character.
-        if ( ch != null && ch.length() > 1 )
-            ch = ch.substring( 0, 1 );
-        setAttribute( "char", ch );
-    }
-
-    
-    public String getChOff()
-    {
-        return getAttribute( "charoff" );
-    }
-    
-    
-    public void setChOff( String chOff )
-    {
-        setAttribute( "charoff", chOff );
-    }
-  
-  
-    public String getVAlign()
-    {
-        return capitalize( getAttribute( "valign" ) );
-    }
-    
-    
-    public void setVAlign( String vAlign )
-    {
-        setAttribute( "valign", vAlign );
-    }
-
-    
-      /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLTableRowElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-  
-  
-    HTMLCollection    _cells;
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLTableSectionElementImpl.java b/src/org/apache/html/dom/HTMLTableSectionElementImpl.java
deleted file mode 100755
index 93abd9f..0000000
--- a/src/org/apache/html/dom/HTMLTableSectionElementImpl.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLTableSectionElement
- * @see ElementImpl
- */
-public final class HTMLTableSectionElementImpl
-    extends HTMLElementImpl
-    implements HTMLTableSectionElement
-{    
-    
-    
-    public String getAlign()
-    {
-        return capitalize( getAttribute( "align" ) );
-    }
-    
-    
-    public void setAlign( String align )
-    {
-        setAttribute( "align", align );
-    }
-      
-    
-    public String getCh()
-    {
-        String    ch;
-        
-        // Make sure that the access key is a single character.
-        ch = getAttribute( "char" );
-        if ( ch != null && ch.length() > 1 )
-            ch = ch.substring( 0, 1 );
-        return ch;
-    }
-    
-    
-    public void setCh( String ch )
-    {
-        // Make sure that the access key is a single character.
-        if ( ch != null && ch.length() > 1 )
-            ch = ch.substring( 0, 1 );
-        setAttribute( "char", ch );
-    }
-
-    
-    public String getChOff()
-    {
-        return getAttribute( "charoff" );
-    }
-    
-    
-    public void setChOff( String chOff )
-    {
-        setAttribute( "charoff", chOff );
-    }
-  
-  
-    public String getVAlign()
-    {
-        return capitalize( getAttribute( "valign" ) );
-    }
-    
-    
-    public void setVAlign( String vAlign )
-    {
-        setAttribute( "valign", vAlign );
-    }
-
-    
-    public HTMLCollection getRows()
-    {
-        if ( _rows == null )
-            _rows = new HTMLCollectionImpl( this, HTMLCollectionImpl.ROW );
-        return _rows;
-    }
-    
-    
-    public HTMLElement insertRow( int index )
-    {
-        HTMLTableRowElementImpl    newRow;
-        
-        newRow = new HTMLTableRowElementImpl( (HTMLDocumentImpl) getOwnerDocument(), "TR" );
-        newRow.insertCell( 0 );
-        if ( insertRowX( index, newRow ) >= 0 )
-            appendChild( newRow );
-        return newRow;
-    }
-    
-    
-    int insertRowX( int index, HTMLTableRowElementImpl newRow )
-    {
-        Node    child;
-        
-        child = getFirstChild();
-        while ( child != null )
-        {
-            if ( child instanceof HTMLTableRowElement )
-            {
-                if ( index == 0 )
-                {
-                    insertBefore( newRow, child );
-                    return -1;
-                }
-                --index;
-            }
-            child = child.getNextSibling();
-        }
-        return index;
-    }
-
-    
-    public void deleteRow( int index )
-    {
-        deleteRowX( index );
-    }
-
-    
-    int deleteRowX( int index )
-    {
-        Node    child;
-        
-        child = getFirstChild();
-        while ( child != null )
-        {
-            if ( child instanceof HTMLTableRowElement )
-            {
-                if ( index == 0 )
-                {
-                    removeChild ( child );
-                    return -1;
-                }
-                --index;
-            }
-            child = child.getNextSibling();
-        }
-        return index;
-    }
-
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLTableSectionElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-    private HTMLCollectionImpl    _rows;
-
-
-}
-
diff --git a/src/org/apache/html/dom/HTMLTextAreaElementImpl.java b/src/org/apache/html/dom/HTMLTextAreaElementImpl.java
deleted file mode 100755
index e5c67c4..0000000
--- a/src/org/apache/html/dom/HTMLTextAreaElementImpl.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLTextAreaElement
- * @see ElementImpl
- */
-public final class HTMLTextAreaElementImpl
-    extends HTMLElementImpl
-    implements HTMLTextAreaElement, HTMLFormControl
-{
-    
-    
-    public String getDefaultValue()
-    {
-        // ! NOT FULLY IMPLEMENTED !
-        return getAttribute( "default-value" );
-    }
-    
-    
-    public void setDefaultValue( String defaultValue )
-    {
-        // ! NOT FULLY IMPLEMENTED !
-        setAttribute( "default-value", defaultValue );
-    }
-  
-  
-
-    public String getAccessKey()
-    {
-        String    accessKey;
-        
-        // Make sure that the access key is a single character.
-        accessKey = getAttribute( "accesskey" );
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        return accessKey;
-    }
-    
-    
-    public void setAccessKey( String accessKey )
-    {
-        // Make sure that the access key is a single character.
-        if ( accessKey != null && accessKey.length() > 1 )
-            accessKey = accessKey.substring( 0, 1 );
-        setAttribute( "accesskey", accessKey );
-    }
-
-    
-    public int getCols()
-    {
-        return getInteger( getAttribute( "cols" ) );
-    }
-    
-    
-    public void setCols( int cols )
-    {
-        setAttribute( "cols", String.valueOf( cols ) );
-    }
-  
-  
-    public boolean getDisabled()
-    {
-        return getBinary( "disabled" );
-    }
-    
-    
-    public void setDisabled( boolean disabled )
-    {
-        setAttribute( "disabled", disabled );
-    }
-
-    
-    public String getName()
-    {
-        return getAttribute( "name" );
-    }
-    
-    
-    public void setName( String name )
-    {
-        setAttribute( "name", name );
-    }
-
-    
-    public boolean getReadOnly()
-    {
-        return getBinary( "readonly" );
-    }
-    
-    
-    public void setReadOnly( boolean readOnly )
-    {
-        setAttribute( "readonly", readOnly );
-    }
-
-    
-       public int getRows()
-    {
-        return getInteger( getAttribute( "rows" ) );
-    }
-    
-    
-    public void setRows( int rows )
-    {
-        setAttribute( "rows", String.valueOf( rows ) );
-    }
-
-  
-       public int getTabIndex()
-    {
-        return getInteger( getAttribute( "tabindex" ) );
-    }
-    
-    
-    public void setTabIndex( int tabIndex )
-    {
-        setAttribute( "tabindex", String.valueOf( tabIndex ) );
-    }
-
-  
-    public String getType()
-    {
-        return getAttribute( "type" );
-    }
-
-    
-      public String getValue()
-    {
-        return getAttribute( "value" );
-    }
-    
-    
-    public void setValue( String value )
-    {
-        setAttribute( "value", value );
-    }
-
-    
-    public void blur()
-    {
-        // No scripting in server-side DOM. This method is moot.
-    }
-    
-    
-    public void focus()
-    {
-        // No scripting in server-side DOM. This method is moot.
-    }
-    
-    
-    public void select()
-    {
-        // No scripting in server-side DOM. This method is moot.
-    }
-    
-      
-      /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLTextAreaElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLTitleElementImpl.java b/src/org/apache/html/dom/HTMLTitleElementImpl.java
deleted file mode 100755
index e54a55a..0000000
--- a/src/org/apache/html/dom/HTMLTitleElementImpl.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLTitleElement
- * @see ElementImpl
- */
-public final class HTMLTitleElementImpl
-    extends HTMLElementImpl
-    implements HTMLTitleElement
-{
- 
-    
-    public String getText()
-    {
-        Node    child;
-        String    text;
-        
-        // Find the Text nodes contained within this element and return their
-        // concatenated value. Required to go around comments, entities, etc.
-        child = getFirstChild();
-        text = "";
-        while ( child != null )
-        {
-            if ( child instanceof Text )
-                text = text + ( (Text) child ).getData();
-            child = child.getNextSibling();
-        }
-        return text;
-    }
-    
-    
-    public void setText( String text )
-    {
-        Node    child;
-        Node    next;
-        
-        // Delete all the nodes and replace them with a single Text node.
-        // This is the only approach that can handle comments and other nodes.
-        child = getFirstChild();
-        while ( child != null )
-        {
-            next = child.getNextSibling();
-            removeChild( child );
-            child = next;
-        }
-        insertBefore( getOwnerDocument().createTextNode( text ), getFirstChild() );
-    }
-
-        
-      /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLTitleElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/HTMLUListElementImpl.java b/src/org/apache/html/dom/HTMLUListElementImpl.java
deleted file mode 100755
index 3f1fb07..0000000
--- a/src/org/apache/html/dom/HTMLUListElementImpl.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.html.dom;
-
-
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@exoffice.com">Assaf Arkin</a>
- * @see org.w3c.dom.html.HTMLUListElement
- * @see ElementImpl
- */
-public final class HTMLUListElementImpl
-    extends HTMLElementImpl
-    implements HTMLUListElement
-{
-    
-    
-    public boolean getCompact()
-    {
-        return getBinary( "compact" );
-    }
-    
-    
-    public void setCompact( boolean compact )
-    {
-        setAttribute( "compact", compact );
-    }
-    
-    
-    public String getType()
-    {
-        return getAttribute( "type" );
-    }
-    
-    
-    public void setType( String type )
-    {
-        setAttribute( "type", type );
-    }
-    
-    
-    /**
-     * Constructor requires owner document.
-     * 
-     * @param owner The owner HTML document
-     */
-    public HTMLUListElementImpl( HTMLDocumentImpl owner, String name )
-    {
-        super( owner, name );
-    }
-
-  
-}
-
diff --git a/src/org/apache/html/dom/Makefile b/src/org/apache/html/dom/Makefile
deleted file mode 100644
index c189730..0000000
--- a/src/org/apache/html/dom/Makefile
+++ /dev/null
@@ -1,67 +0,0 @@
-# Makefile for directory ./org/apache/html/dom
-
-TARGETS=\
-	HTMLAnchorElementImpl.class\
-	HTMLAppletElementImpl.class\
-	HTMLAreaElementImpl.class\
-	HTMLBRElementImpl.class\
-	HTMLBaseElementImpl.class\
-	HTMLBaseFontElementImpl.class\
-	HTMLBodyElementImpl.class\
-	HTMLBuilder.class\
-	HTMLButtonElementImpl.class\
-	HTMLCollectionImpl.class\
-	HTMLDListElementImpl.class\
-	HTMLDOMImplementationImpl.class\
-	HTMLDirectoryElementImpl.class\
-	HTMLDivElementImpl.class\
-	HTMLDocumentImpl.class\
-	HTMLElementImpl.class\
-	HTMLFieldSetElementImpl.class\
-	HTMLFontElementImpl.class\
-	HTMLFormControl.class\
-	HTMLFormElementImpl.class\
-	HTMLFrameElementImpl.class\
-	HTMLFrameSetElementImpl.class\
-	HTMLHRElementImpl.class\
-	HTMLHeadElementImpl.class\
-	HTMLHeadingElementImpl.class\
-	HTMLHtmlElementImpl.class\
-	HTMLIFrameElementImpl.class\
-	HTMLImageElementImpl.class\
-	HTMLInputElementImpl.class\
-	HTMLIsIndexElementImpl.class\
-	HTMLLIElementImpl.class\
-	HTMLLabelElementImpl.class\
-	HTMLLegendElementImpl.class\
-	HTMLLinkElementImpl.class\
-	HTMLMapElementImpl.class\
-	HTMLMenuElementImpl.class\
-	HTMLMetaElementImpl.class\
-	HTMLModElementImpl.class\
-	HTMLOListElementImpl.class\
-	HTMLObjectElementImpl.class\
-	HTMLOptGroupElementImpl.class\
-	HTMLOptionElementImpl.class\
-	HTMLParagraphElementImpl.class\
-	HTMLParamElementImpl.class\
-	HTMLPreElementImpl.class\
-	HTMLQuoteElementImpl.class\
-	HTMLScriptElementImpl.class\
-	HTMLSelectElementImpl.class\
-	HTMLStyleElementImpl.class\
-	HTMLTableCaptionElementImpl.class\
-	HTMLTableCellElementImpl.class\
-	HTMLTableColElementImpl.class\
-	HTMLTableElementImpl.class\
-	HTMLTableRowElementImpl.class\
-	HTMLTableSectionElementImpl.class\
-	HTMLTextAreaElementImpl.class\
-	HTMLTitleElementImpl.class\
-	HTMLUListElementImpl.class\
-	NameNodeListImpl.class
-
-DIRS = 
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/html/dom/NameNodeListImpl.java b/src/org/apache/html/dom/NameNodeListImpl.java
deleted file mode 100644
index 94a6d37..0000000
--- a/src/org/apache/html/dom/NameNodeListImpl.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.html.dom;
-
-import org.w3c.dom.*;
-import java.util.Vector;
-import org.apache.xerces.dom.NodeImpl;
-import org.apache.xerces.dom.ElementImpl;
-import org.apache.xerces.dom.DeepNodeListImpl;
-
-/**
- * This class implements the DOM's NodeList behavior for
- * HTMLDocuemnt.getElementsByName().
- *
- * @version
- * @since  PR-DOM-Level-1-19980818.
- * @see DeepNodeListImpl
- */
-public class NameNodeListImpl 
-    extends DeepNodeListImpl
-    implements NodeList {
-    
-    
-    /** Constructor. */
-    public NameNodeListImpl(NodeImpl rootNode, String tagName) {
-	super( rootNode, tagName );
-    }  
-    
-
-    /** 
-     * Iterative tree-walker. When you have a Parent link, there's often no
-     * need to resort to recursion. NOTE THAT only Element nodes are matched
-     * since we're specifically supporting getElementsByTagName().
-     */
-    protected Node nextMatchingElementAfter(Node current) {
-        
-        Node next;
-        while (current != null) {
-            // Look down to first child.
-            if (current.hasChildNodes()) {
-                current = (current.getFirstChild());
-            }
-            
-            // Look right to sibling (but not from root!)
-            else if (current != rootNode && null != (next = current.getNextSibling())) {
-                current = next;
-            }
-            
-            // Look up and right (but not past root!)
-            else {
-                next = null;
-                for (; current != rootNode; // Stop when we return to starting point
-                     current = current.getParentNode()) {
-                    
-                    next = current.getNextSibling();
-                    if (next != null)
-                        break;
-                }
-                current = next;
-            }
-            
-            // Have we found an Element with the right tagName?
-            // ("*" matches anything.)
-            if (current != rootNode && current != null
-                && current.getNodeType() ==  Node.ELEMENT_NODE  ) {
-                String name = ((ElementImpl) current).getAttribute( "name" );
-                if ( name.equals("*") || name.equals(tagName))
-                    return current;
-            }
-            
-            // Otherwise continue walking the tree
-        }
-        
-        // Fell out of tree-walk; no more instances found
-        return null;
-        
-    } // nextMatchingElementAfter(int):Node
-    
-} // class NameNodeListImpl
diff --git a/src/org/apache/wml/Makefile b/src/org/apache/wml/Makefile
deleted file mode 100644
index d9507c7..0000000
--- a/src/org/apache/wml/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-# Makefile for directory ./org/apache/wml
-
-TARGETS=\
-      WMLAElement.class\
-      WMLAccessElement.class\
-      WMLAnchorElement.class\
-      WMLBElement.class\
-      WMLBigElement.class\
-      WMLBrElement.class\
-      WMLCardElement.class\
-      WMLDOMImplementation.class\
-      WMLDoElement.class\
-      WMLDocument.class\
-      WMLElement.class\
-      WMLEmElement.class\
-      WMLFieldsetElement.class\
-      WMLGoElement.class\
-      WMLHeadElement.class\
-      WMLIElement.class\
-      WMLImgElement.class\
-      WMLInputElement.class\
-      WMLMetaElement.class\
-      WMLNoopElement.class\
-      WMLOneventElement.class\
-      WMLOptgroupElement.class\
-      WMLOptionElement.class\
-      WMLPElement.class\
-      WMLPostfieldElement.class\
-      WMLPrevElement.class\
-      WMLRefreshElement.class\
-      WMLSelectElement.class\
-      WMLSetvarElement.class\
-      WMLSmallElement.class\
-      WMLStrongElement.class\
-      WMLTableElement.class\
-      WMLTdElement.class\
-      WMLTemplateElement.class\
-      WMLTimerElement.class\
-      WMLTrElement.class\
-      WMLUElement.class\
-      WMLWmlElement.class
-
-DIRS = dom
-
-TOP = ../../../..
-include $(TOP)/src/Makefile.incl
-
diff --git a/src/org/apache/wml/WMLAElement.java b/src/org/apache/wml/WMLAElement.java
deleted file mode 100644
index 9b9c0d6..0000000
--- a/src/org/apache/wml/WMLAElement.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLAElement extends WMLElement {
-
-    public void setHref(String newValue);
-    public String getHref();
-
-    public void setTitle(String newValue);
-    public String getTitle();
-
-    public void setId(String newValue);
-    public String getId();
-
-    /**
-     * 'xml:lang' specifics the natural or formal language in which
-     * the document is written.  
-     * (Section 8.8, WAP WML Version 16-Jun-1999) 
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLAccessElement.java b/src/org/apache/wml/WMLAccessElement.java
deleted file mode 100644
index 8ce55c2..0000000
--- a/src/org/apache/wml/WMLAccessElement.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'access' element specifics the access control for the entire deck
- * (Section 11.3.1, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLAccessElement extends WMLElement {
-
-    /**
-     * A deck's domain and path attributes specify which deck may
-     * access it.  
-     *
-     * domain attribute is suffix-matched against the domain name
-     * portion of the referring URI 
-     */
-    public void setDomain(String newValue);
-    public String getDomain();
-
-    /**
-     * path attribute is prefix-matched against the path portion of
-     * the referring URI 
-     */
-    public void setPath(String newValue);
-    public String getPath();
-}
diff --git a/src/org/apache/wml/WMLAnchorElement.java b/src/org/apache/wml/WMLAnchorElement.java
deleted file mode 100644
index f8d0e19..0000000
--- a/src/org/apache/wml/WMLAnchorElement.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLAnchorElement extends WMLElement {
-
-    public void setTitle(String newValue);
-    public String getTitle();
-
-    /**
-     * 'xml:lang' specifics the natural or formal language in which
-     * the document is written.  
-     * (Section 8.8, WAP WML Version 16-Jun-1999) 
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLBElement.java b/src/org/apache/wml/WMLBElement.java
deleted file mode 100644
index 0a1d152..0000000
--- a/src/org/apache/wml/WMLBElement.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'b' element boldface the text
- * (Section 11.8.1, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLBElement extends WMLElement {
-    /**
-     * 'xml:lang' specifics the natural or formal language in which
-     * the document is written.  
-     * (Section 8.8, WAP WML Version 16-Jun-1999) 
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLBigElement.java b/src/org/apache/wml/WMLBigElement.java
deleted file mode 100644
index e7197a2..0000000
--- a/src/org/apache/wml/WMLBigElement.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'big' element renders the text with big font
- * (Section 11.8.1, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLBigElement extends WMLElement {
-    /**
-     * 'xml:lang' specifics the natural or formal language in which
-     * the document is written.  
-     * (Section 8.8, WAP WML Version 16-Jun-1999) 
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLBrElement.java b/src/org/apache/wml/WMLBrElement.java
deleted file mode 100644
index 0660125..0000000
--- a/src/org/apache/wml/WMLBrElement.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'br' element starts a new line</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLBrElement extends WMLElement {
-    /**
-     * 'xml:lang' specifics the natural or formal language in which
-     * the document is written.  
-     * (Section 8.8, WAP WML Version 16-Jun-1999) 
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLCardElement.java b/src/org/apache/wml/WMLCardElement.java
deleted file mode 100644
index 599bda6..0000000
--- a/src/org/apache/wml/WMLCardElement.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'card' element is the basic display unit of WML. A WML decks
- * contains a collection of cards.
- * (Section 11.5, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLCardElement extends WMLElement {
-
-    /**
-     * 'onenterbackward' specifies the event to occur when a user
-     * agent into a card using a 'go' task
-     * (Section 11.5.1, WAP WML Version 16-Jun-1999)
-     */
-    public void setOnEnterBackward(String href);
-    public String getOnEnterBackward();
-
-    /**
-     * 'onenterforward' specifies the event to occur when a user
-     * agent into a card using a 'prev' task
-     * (Section 11.5.1, WAP WML Version 16-Jun-1999)
-     */
-    public void setOnEnterForward(String href);
-    public String getOnEnterForward();
-
-    /**
-     * 'onenterbackward' specifies the event to occur when a timer expires
-     * (Section 11.5.1, WAP WML Version 16-Jun-1999)
-     */
-    public void setOnTimer(String href);
-    public String getOnTimer();
-
-    /**
-     * 'title' specifies a advisory info about the card
-     * (Section 11.5.2, WAP WML Version 16-Jun-1999)
-     */
-    public void setTitle(String newValue);
-    public String getTitle();
-
-    /**
-     * 'newcontext' specifies whether a browser context should be
-     * re-initialized upon entering the card. Default to be false.
-     * (Section 11.5.2, WAP WML Version 16-Jun-1999)
-     */
-    public void setNewContext(boolean newValue);
-    public boolean getNewContext();
-    
-    /**
-     *  'ordered' attribute specifies a hit to user agent about the
-     *  organization of the card's content 
-     * (Section 11.5.2, WAP WML Version 16-Jun-1999)
-     */
-    public void setOrdered(boolean newValue);
-    public boolean getOrdered();
-
-    /**
-     * 'xml:lang' specifics the natural or formal language in which
-     * the document is written.  
-     * (Section 8.8, WAP WML Version 16-Jun-1999) 
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLDOMImplementation.java b/src/org/apache/wml/WMLDOMImplementation.java
deleted file mode 100644
index 491ffa0..0000000
--- a/src/org/apache/wml/WMLDOMImplementation.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-import org.w3c.dom.*;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-public interface WMLDOMImplementation extends DOMImplementation {
-}
diff --git a/src/org/apache/wml/WMLDoElement.java b/src/org/apache/wml/WMLDoElement.java
deleted file mode 100644
index c5dfd8f..0000000
--- a/src/org/apache/wml/WMLDoElement.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLDoElement extends WMLElement {
-
-    public void setOptional(String newValue);
-    public String getOptional();
-
-    public void setLabel(String newValue);
-    public String getLabel();
-
-    public void setType(String newValue);
-    public String getType();
-
-    public void setName(String newValue);
-    public String getName();
-
-    /**
-     * The xml:lang that specifics the natural or formal language in
-     * which the document is written.
-     * (Section 8.8, WAP WML Version 16-Jun-1999)
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLDocument.java b/src/org/apache/wml/WMLDocument.java
deleted file mode 100644
index 892e907..0000000
--- a/src/org/apache/wml/WMLDocument.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-import org.w3c.dom.*;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLDocument extends Document {
-}
diff --git a/src/org/apache/wml/WMLElement.java b/src/org/apache/wml/WMLElement.java
deleted file mode 100644
index 96b7b3b..0000000
--- a/src/org/apache/wml/WMLElement.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-import org.w3c.dom.Element;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>All WML Elements are derived from this class that contains two
- * core attributes defined in the DTD.</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLElement extends Element {
-
-    /**
-     * The element's identifier which is unique in a single deck. 
-     * (Section 8.9, WAP WML Version 16-Jun-1999)
-     */
-    public void setId(String newValue);
-    public String getId();
-
-    /**
-     * The 'class' attribute of a element that affiliates an elements
-     * with one or more elements.
-     * (Section 8.9, WAP WML Version 16-Jun-1999)
-     */
-    public void setClassName(String newValue);
-    public String getClassName();
-}
diff --git a/src/org/apache/wml/WMLEmElement.java b/src/org/apache/wml/WMLEmElement.java
deleted file mode 100644
index 92304ba..0000000
--- a/src/org/apache/wml/WMLEmElement.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'em' element emphasis the text
- * (Section 11.8.1, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLEmElement extends WMLElement {
-    /**
-     * The xml:lang that specifics the natural or formal language in
-     * which the document is written.
-     * (Section 8.8, WAP WML Version 16-Jun-1999)
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLFieldsetElement.java b/src/org/apache/wml/WMLFieldsetElement.java
deleted file mode 100644
index 20ed9c5..0000000
--- a/src/org/apache/wml/WMLFieldsetElement.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'fieldset' element groups related fields and tet 
- * (Section 11.6.4, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-public interface WMLFieldsetElement extends WMLElement {
-
-    /**
-     * 'title' specifies a title for this element
-     */
-    public void setTitle(String newValue);
-    public String getTitle();
-
-    /**
-     * The xml:lang that specifics the natural or formal language in
-     * which the document is written.
-     * (Section 8.8, WAP WML Version 16-Jun-1999)
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLGoElement.java b/src/org/apache/wml/WMLGoElement.java
deleted file mode 100644
index ef37e8f..0000000
--- a/src/org/apache/wml/WMLGoElement.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLGoElement extends WMLElement {
-
-  public void setSendreferer(String newValue);
-
-  public String getSendreferer();
-
-  public void setAcceptCharset(String newValue);
-
-  public String getAcceptCharset();
-
-  public void setHref(String newValue);
-
-  public String getHref();
-
-  public void setMethod(String newValue);
-
-  public String getMethod();
-
-}
diff --git a/src/org/apache/wml/WMLHeadElement.java b/src/org/apache/wml/WMLHeadElement.java
deleted file mode 100644
index 14f0d7e..0000000
--- a/src/org/apache/wml/WMLHeadElement.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>The head element contains information about a deck.
- * (Section 11.3, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLHeadElement extends WMLElement {
-}
diff --git a/src/org/apache/wml/WMLIElement.java b/src/org/apache/wml/WMLIElement.java
deleted file mode 100644
index 787cdc6..0000000
--- a/src/org/apache/wml/WMLIElement.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'i' italic the text
- * (Section 11.8.1, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLIElement extends WMLElement {
-    /**
-     * The xml:lang that specifics the natural or formal language in
-     * which the document is written.
-     * (Section 8.8, WAP WML Version 16-Jun-1999)
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLImgElement.java b/src/org/apache/wml/WMLImgElement.java
deleted file mode 100644
index b0773a6..0000000
--- a/src/org/apache/wml/WMLImgElement.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'img' specifies an image in a text flow
- * (Section 11.9, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-public interface WMLImgElement extends WMLElement {
-
-    /**
-     * 'alt' specifies an alternative text for the image
-     * (Section 11.9, WAP WML Version 16-Jun-1999)
-     */
-    public void setAlt(String newValue);
-    public String getAlt();
-
-    /**
-     * 'src' specifies URI for the source images
-     * (Section 11.9, WAP WML Version 16-Jun-1999)
-     */
-    public void setSrc(String newValue);
-    public String getSrc();
-
-    /**
-     * 'localsrc' specifies an alternative internal representation of
-     * the image.
-     * (Section 11.9, WAP WML Version 16-Jun-1999) 
-     */
-    public void setLocalSrc(String newValue);
-    public String getLocalSrc();
-
-    /**
-     * 'vspace' specifies the abount of white space to be inserted
-     * above and below
-     * (Section 11.9, WAP WML Version 16-Jun-1999) 
-     */
-    public void setVspace(String newValue);
-    public String getVspace();
-
-    /**
-     * 'hspace' specifies the abount of white space to be inserted
-     * left and right
-     * (Section 11.9, WAP WML Version 16-Jun-1999) 
-     */
-    public void setHspace(String newValue);
-    public String getHspace();
-
-    /**
-     * 'align' specifies the alignment of the image within the text
-     * flow.
-     * (Section 11.8, WAP WML Version 16-Jun-1999)
-     */
-    public void setAlign(String newValue);
-    public String getAlign();
-
-    /**
-     * 'width' specifies the width of an image.
-     * (Section 11.9, WAP WML Version 16-Jun-1999)
-     */
-    public void setWidth(String newValue);
-    public String getWidth();
-
-    /**
-     * 'height' specifies the height of an image.
-     * (Section 11.9, WAP WML Version 16-Jun-1999)
-     */
-    public void setHeight(String newValue);
-    public String getHeight();
-
-    /**
-     * The xml:lang that specifics the natural or formal language in
-     * which the document is written.
-     * (Section 8.8, WAP WML Version 16-Jun-1999)
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLInputElement.java b/src/org/apache/wml/WMLInputElement.java
deleted file mode 100644
index 8bff3a5..0000000
--- a/src/org/apache/wml/WMLInputElement.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'input' element specifies a text entry object.
- * (Section 11.6.3, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLInputElement extends WMLElement {
-
-    /**
-     * 'name' specifies the name of a variable after the user enters the text.
-     * (Section 11.6.3, WAP WML Version 16-Jun-1999)
-     */
-    public void setName(String newValue);
-    public String getName();
-
-    /**
-     * 'value' specifies the default value of the variable in 'name' attribute
-     * (Section 11.6.3, WAP WML Version 16-Jun-1999)
-     */
-    public void setValue(String newValue);
-    public String getValue();
-
-    /**
-     * 'type' specifies the type of text input area. 
-     * Two values are allowed: 'text' and 'password' and default is 'text'
-     * (Section 11.6.3, WAP WML Version 16-Jun-1999)
-     */
-    public void setType(String newValue);
-    public String getType();
-
-    /**
-     * 'format' specifies the input mask for user input.
-     * (Section 11.6.3, WAP WML Version 16-Jun-1999)
-     */
-    public void setFormat(String newValue);
-    public String getFormat();
-
-    /**
-     * 'emptyok' specifies whether a empty input is allowed when a
-     * non-empty 'format' is specified. Default to be 'false'
-     * (Section 11.6.3, WAP WML Version 16-Jun-1999)
-     */
-    public void setEmptyOk(boolean newValue);
-    public boolean getEmptyOk();
-
-    /**
-     * 'size' specifies the width of the input in characters
-     * (Section 11.6.3, WAP WML Version 16-Jun-1999)
-     */
-    public void setSize(int newValue);
-    public int getSize();
-
-    /**
-     * 'maxlength' specifies the maximum number of characters to be
-     * enter.
-     * (Section 11.6.3, WAP WML Version 16-Jun-1999) 
-     */
-    public void setMaxLength(int newValue);
-    public int getMaxLength();
-
-    /**
-     * 'title' specifies a title for this element
-     * (Section 11.6.3, WAP WML Version 16-Jun-1999) 
-     */
-    public void setTitle(String newValue);
-    public String getTitle();
-
-    /**
-     * 'tabindex' specifies the tabbing position of the element
-     * (Section 11.6.1, WAP WML Version 16-Jun-1999)
-     */
-    public void setTabIndex(int newValue);
-    public int getTabIndex();
-
-    /**
-     * 'xml:lang' specifics the natural or formal language in which
-     * the document is written.  
-     * (Section 8.8, WAP WML Version 16-Jun-1999) 
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLMetaElement.java b/src/org/apache/wml/WMLMetaElement.java
deleted file mode 100644
index bdda8a9..0000000
--- a/src/org/apache/wml/WMLMetaElement.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>The meta element contains meta-info of an WML deck
- * (Section 11.3.2, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-public interface WMLMetaElement extends WMLElement {
-
-    /**
-     * 'name' attribute specific the property name
-     */
-    public void setName(String newValue);
-    public String getName();
-
-    /**
-     * 'http-equiv' attribute indicates the property should be
-     * interpret as HTTP header.
-     */
-    public void setHttpEquiv(String newValue);
-    public String getHttpEquiv();
-
-    /**
-     * 'forua' attribute specifies whether a intermediate agent should
-     * remove this meta element. A value of false means the
-     * intermediate agent must remove the element.
-     */
-    public void setForua(boolean newValue);
-    public boolean getForua();
-
-    /**
-     * 'scheme' attribute specifies a form that may be used to
-     * interpret the property value 
-     */
-    public void setScheme(String newValue);
-    public String getScheme();
-
-    /**
-     * 'content' attribute specifies the property value 
-     */
-    public void setContent(String newValue);
-    public String getContent();
-}
diff --git a/src/org/apache/wml/WMLNoopElement.java b/src/org/apache/wml/WMLNoopElement.java
deleted file mode 100644
index b37dad8..0000000
--- a/src/org/apache/wml/WMLNoopElement.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-public interface WMLNoopElement extends WMLElement {
-}
diff --git a/src/org/apache/wml/WMLOneventElement.java b/src/org/apache/wml/WMLOneventElement.java
deleted file mode 100644
index 7ca4c18..0000000
--- a/src/org/apache/wml/WMLOneventElement.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLOneventElement extends WMLElement {
-
-  public void setType(String newValue);
-
-  public String getType();
-
-}
diff --git a/src/org/apache/wml/WMLOptgroupElement.java b/src/org/apache/wml/WMLOptgroupElement.java
deleted file mode 100644
index fac2ca0..0000000
--- a/src/org/apache/wml/WMLOptgroupElement.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'optgroup' element groups related 'option' elements into a
- * hierarchy. (Section 11.6.2.2, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLOptgroupElement extends WMLElement {
-
-    /**
-     * 'title' specifies the title of this element
-     * (Section 11.6.2.3, WAP WML Version 16-Jun-1999)
-     */
-    public void setTitle(String newValue);
-    public String getTitle();
-
-    /**
-     * 'xml:lang' specifics the natural or formal language in which
-     * the document is written.  
-     * (Section 8.8, WAP WML Version 16-Jun-1999) 
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLOptionElement.java b/src/org/apache/wml/WMLOptionElement.java
deleted file mode 100644
index 67d20cc..0000000
--- a/src/org/apache/wml/WMLOptionElement.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'option' element specifies a choice in a 'select' element</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLOptionElement extends WMLElement {
-
-    /**
-     * 'value' specifies the value to used to set the 'name' variable
-     * (Section 11.6.2.2, WAP WML Version 16-Jun-1999)
-     */
-    public void setValue(String newValue);
-    public String getValue();
-
-    /**
-     * 'title' specifies a title for this element.
-     * (Section 11.6.2.2, WAP WML Version 16-Jun-1999)
-     */
-    public void setTitle(String newValue);
-    public String getTitle();
-
-    /**
-     * 'onpick' specifies a event to occur when a user select and
-     * disselect this choice.
-     * (Section 11.6.2.2, WAP WML Version 16-Jun-1999) */
-    public void setOnPick(String href);
-    public String getOnPick();
-
-    /**
-     * 'xml:lang' specifics the natural or formal language in which
-     * the document is written.  
-     * (Section 8.8, WAP WML Version 16-Jun-1999) 
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLPElement.java b/src/org/apache/wml/WMLPElement.java
deleted file mode 100644
index a4de57d..0000000
--- a/src/org/apache/wml/WMLPElement.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'p' element specifies a paragraph
- * (Section 11.8.3, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLPElement extends WMLElement {
-
-    /**
-     * 'mode' specifies the wrapping mode of the paragraph.
-     * The legal values are 'wrap' and 'nowrap'
-     * (Section 11.8.3, WAP WML Version 16-Jun-1999)
-     */
-    public void setMode(String newValue);
-    public String getMode();
-
-    /**
-     * 'align' specifies the align of teh paragraph
-     * The legal values are 'left,' 'center,' and 'right'
-     * (Section 11.8.3, WAP WML Version 16-Jun-1999)
-     */
-    public void setAlign(String newValue);
-    public String getAlign();
-
-    /**
-     * The xml:lang that specifics the natural or formal language in
-     * which the document is written.
-     * (Section 8.8, WAP WML Version 16-Jun-1999)
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLPostfieldElement.java b/src/org/apache/wml/WMLPostfieldElement.java
deleted file mode 100644
index 60654c0..0000000
--- a/src/org/apache/wml/WMLPostfieldElement.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLPostfieldElement extends WMLElement {
-
-  public void setValue(String newValue);
-
-  public String getValue();
-
-  public void setName(String newValue);
-
-  public String getName();
-
-}
diff --git a/src/org/apache/wml/WMLPrevElement.java b/src/org/apache/wml/WMLPrevElement.java
deleted file mode 100644
index d359c47..0000000
--- a/src/org/apache/wml/WMLPrevElement.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLPrevElement extends WMLElement {
-}
diff --git a/src/org/apache/wml/WMLRefreshElement.java b/src/org/apache/wml/WMLRefreshElement.java
deleted file mode 100644
index 4ddb775..0000000
--- a/src/org/apache/wml/WMLRefreshElement.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLRefreshElement extends WMLElement {
-}
diff --git a/src/org/apache/wml/WMLSelectElement.java b/src/org/apache/wml/WMLSelectElement.java
deleted file mode 100644
index 7f65d7a..0000000
--- a/src/org/apache/wml/WMLSelectElement.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'select' element lets user pick from a list of options.
- * (Section 11.6.2.1, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-public interface WMLSelectElement extends WMLElement {
-    
-    /**
-     * 'tabindex' specifies the tabbing position of the element
-     * (Section 11.6.1, WAP WML Version 16-Jun-1999)
-     */
-    public void setTabIndex(int newValue);
-    public int getTabIndex();
-
-    /**
-     * 'multiple' indicates whether a list accept multiple selection
-     * (Section 11.6.2.1, WAP WML Version 16-Jun-1999)
-     */
-    public void setMultiple(boolean newValue);
-    public boolean getMultiple();
-
-    /**
-     * 'name' specifies the name of variable to be set.
-     * (Section 11.6.2.1, WAP WML Version 16-Jun-1999)
-     */
-    public void setName(String newValue);
-    public String getName();
-
-    /**
-     * 'value' specifics the default value of the variable of 'name'
-     * (Section 11.6.2.1, WAP WML Version 16-Jun-1999)
-     */
-    public void setValue(String newValue);
-    public String getValue();
-
-    /**
-     * 'title' specifies a title for this element
-     * (Section 11.6.2.1, WAP WML Version 16-Jun-1999)
-     */
-    public void setTitle(String newValue);
-    public String getTitle();
-
-    /**
-     * 'iname' specifies name of variable to be set with the index
-     * result of selection.  
-     * (Section 11.6.2.1, WAP WML Version 16-Jun-1999)
-     */
-    public void setIName(String newValue);
-    public String getIName();
-
-    /**
-     * 'ivalue' specifies the default of the variable 'iname'
-     */
-    public void setIValue(String newValue);
-    public String getIValue();
-
-    /**
-     * 'xml:lang' specifics the natural or formal language in which
-     * the document is written.  
-     * (Section 8.8, WAP WML Version 16-Jun-1999) 
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLSetvarElement.java b/src/org/apache/wml/WMLSetvarElement.java
deleted file mode 100644
index d3f39ad..0000000
--- a/src/org/apache/wml/WMLSetvarElement.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLSetvarElement extends WMLElement {
-
-  public void setValue(String newValue);
-
-  public String getValue();
-
-  public void setName(String newValue);
-
-  public String getName();
-
-}
diff --git a/src/org/apache/wml/WMLSmallElement.java b/src/org/apache/wml/WMLSmallElement.java
deleted file mode 100644
index 8211284..0000000
--- a/src/org/apache/wml/WMLSmallElement.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-/**
- * 'small' render the text with small font
- * (Section 11.8.1, WAP WML Version 16-Jun-1999)
- */
-public interface WMLSmallElement extends WMLElement {
-    /**
-     * The xml:lang that specifics the natural or formal language in
-     * which the document is written.
-     * (Section 8.8, WAP WML Version 16-Jun-1999)
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLStrongElement.java b/src/org/apache/wml/WMLStrongElement.java
deleted file mode 100644
index cc48123..0000000
--- a/src/org/apache/wml/WMLStrongElement.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'strong' strongly emphasis the text
- * (Section 11.8.1, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLStrongElement extends WMLElement {
-    /**
-     * The xml:lang that specifics the natural or formal language in
-     * which the document is written.
-     * (Section 8.8, WAP WML Version 16-Jun-1999)
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLTableElement.java b/src/org/apache/wml/WMLTableElement.java
deleted file mode 100644
index 8afd7f2..0000000
--- a/src/org/apache/wml/WMLTableElement.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'table' create a set of aligned columns of text and images.
- * (Section 11.8.5, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLTableElement extends WMLElement {
-
-    /**
-     * 'title' specifies a title for the table
-     * (Section 11.8.5, WAP WML Version 16-Jun-1999)
-     */
-    public void setTitle(String newValue);
-    public String getTitle();
-
-    /**
-     * 'align' set the align of the table
-     * (Section 11.8.5, WAP WML Version 16-Jun-1999)
-     */
-    public void setAlign(String newValue);
-    public String getAlign();
-
-    /**
-     * 'columns' specifies the number of columns
-     * (Section 11.8.5, WAP WML Version 16-Jun-1999)
-     */
-    public void setColumns(int newValue);
-    public int getColumns();
-
-    /**
-     * The xml:lang that specifics the natural or formal language in
-     * which the document is written.
-     * (Section 8.8, WAP WML Version 16-Jun-1999)
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLTdElement.java b/src/org/apache/wml/WMLTdElement.java
deleted file mode 100644
index 118f3fe..0000000
--- a/src/org/apache/wml/WMLTdElement.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'td' specifies a single table cell with in a row
- * (Section 11.8.6, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLTdElement extends WMLElement {
-    /**
-     * The xml:lang that specifics the natural or formal language in
-     * which the document is written.
-     * (Section 8.8, WAP WML Version 16-Jun-1999)
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLTemplateElement.java b/src/org/apache/wml/WMLTemplateElement.java
deleted file mode 100644
index 166145d..0000000
--- a/src/org/apache/wml/WMLTemplateElement.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>The 'template' element declares a template for the cards in the deck.</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLTemplateElement extends WMLElement {
-
-    public void setOnTimer(String newValue);
-    public String getOnTimer();
-
-    public void setOnEnterBackward(String newValue);
-    public String getOnEnterBackward();
-
-    public void setOnEnterForward(String newValue);
-    public String getOnEnterForward();
-}
diff --git a/src/org/apache/wml/WMLTimerElement.java b/src/org/apache/wml/WMLTimerElement.java
deleted file mode 100644
index 44b0017..0000000
--- a/src/org/apache/wml/WMLTimerElement.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'timer' elements declares a card timer.
- * (Section 11.6.7, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLTimerElement extends WMLElement {
-    /**
-     * 'name' specifies the name of variable ot be set with the value
-     * of the timer.
-     * (Section 11.6.7, WAP WML Version 16-Jun-1999)
-     */
-    public void setName(String newValue);
-    public String getName();
-
-    /**
-     * 'value' indicates teh default of the variable 'name'
-     * (Section 11.6.7, WAP WML Version 16-Jun-1999)
-     */
-    public void setValue(String newValue);
-    public String getValue();
-}
diff --git a/src/org/apache/wml/WMLTrElement.java b/src/org/apache/wml/WMLTrElement.java
deleted file mode 100644
index df83b39..0000000
--- a/src/org/apache/wml/WMLTrElement.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'tr' specifies a single row
- * (Section 11.8.6, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLTrElement extends WMLElement {
-}
diff --git a/src/org/apache/wml/WMLUElement.java b/src/org/apache/wml/WMLUElement.java
deleted file mode 100644
index b2716e5..0000000
--- a/src/org/apache/wml/WMLUElement.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'u' underline the text
- * (Section 11.8.1, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLUElement extends WMLElement {
-    /**
-     * The xml:lang that specifics the natural or formal language in
-     * which the document is written.
-     * (Section 8.8, WAP WML Version 16-Jun-1999)
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/WMLWmlElement.java b/src/org/apache/wml/WMLWmlElement.java
deleted file mode 100644
index 1eee436..0000000
--- a/src/org/apache/wml/WMLWmlElement.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml;
-
-/**
- * <p>The interface is modeled after DOM1 Spec for HTML from W3C.
- * The DTD used in this DOM model is from 
- * <a href="http://www.wapforum.org/DTD/wml_1.1.xml">
- * http://www.wapforum.org/DTD/wml_1.1.xml</a></p>
- *
- * <p>'wml' is the root oot of a WML document.
- * (Section 11.2, WAP WML Version 16-Jun-1999)</p>
- *
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public interface WMLWmlElement extends WMLElement {
-    /**
-     * The xml:lang that specifics the natural or formal language in
-     * which the document is written.
-     * (Section 8.8, WAP WML Version 16-Jun-1999)
-     */
-    public void setXmlLang(String newValue);
-    public String getXmlLang();
-}
diff --git a/src/org/apache/wml/dom/Makefile b/src/org/apache/wml/dom/Makefile
deleted file mode 100644
index ff7278c..0000000
--- a/src/org/apache/wml/dom/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-# Makefile for directory ./org/apache/wml/dom
-
-TARGETS=\
-      WMLAElementImpl.class\
-      WMLAccessElementImpl.class\
-      WMLAnchorElementImpl.class\
-      WMLBElementImpl.class\
-      WMLBigElementImpl.class\
-      WMLBrElementImpl.class\
-      WMLCardElementImpl.class\
-      WMLDOMImplementationImpl.class\
-      WMLDoElementImpl.class\
-      WMLDocumentImpl.class\
-      WMLElementImpl.class\
-      WMLEmElementImpl.class\
-      WMLFieldsetElementImpl.class\
-      WMLGoElementImpl.class\
-      WMLHeadElementImpl.class\
-      WMLIElementImpl.class\
-      WMLImgElementImpl.class\
-      WMLInputElementImpl.class\
-      WMLMetaElementImpl.class\
-      WMLNoopElementImpl.class\
-      WMLOneventElementImpl.class\
-      WMLOptgroupElementImpl.class\
-      WMLOptionElementImpl.class\
-      WMLPElementImpl.class\
-      WMLPostfieldElementImpl.class\
-      WMLPrevElementImpl.class\
-      WMLRefreshElementImpl.class\
-      WMLSelectElementImpl.class\
-      WMLSetvarElementImpl.class\
-      WMLSmallElementImpl.class\
-      WMLStrongElementImpl.class\
-      WMLTableElementImpl.class\
-      WMLTdElementImpl.class\
-      WMLTemplateElementImpl.class\
-      WMLTimerElementImpl.class\
-      WMLTrElementImpl.class\
-      WMLUElementImpl.class\
-      WMLWmlElementImpl.class
-
-DIRS = 
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/wml/dom/WMLAElementImpl.java b/src/org/apache/wml/dom/WMLAElementImpl.java
deleted file mode 100644
index c7965d8..0000000
--- a/src/org/apache/wml/dom/WMLAElementImpl.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLAElementImpl extends WMLElementImpl implements WMLAElement {
-
-  public WMLAElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setHref(String newValue) {
-    setAttribute("href", newValue);
-  }
-
-  public String getHref() {
-    return getAttribute("href");
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setTitle(String newValue) {
-    setAttribute("title", newValue);
-  }
-
-  public String getTitle() {
-    return getAttribute("title");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLAccessElementImpl.java b/src/org/apache/wml/dom/WMLAccessElementImpl.java
deleted file mode 100644
index 12bea44..0000000
--- a/src/org/apache/wml/dom/WMLAccessElementImpl.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLAccessElementImpl extends WMLElementImpl implements WMLAccessElement {
-
-  public WMLAccessElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setDomain(String newValue) {
-    setAttribute("domain", newValue);
-  }
-
-  public String getDomain() {
-    return getAttribute("domain");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-  public void setPath(String newValue) {
-    setAttribute("path", newValue);
-  }
-
-  public String getPath() {
-    return getAttribute("path");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLAnchorElementImpl.java b/src/org/apache/wml/dom/WMLAnchorElementImpl.java
deleted file mode 100644
index df87ed9..0000000
--- a/src/org/apache/wml/dom/WMLAnchorElementImpl.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLAnchorElementImpl extends WMLElementImpl implements WMLAnchorElement {
-
-  public WMLAnchorElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setTitle(String newValue) {
-    setAttribute("title", newValue);
-  }
-
-  public String getTitle() {
-    return getAttribute("title");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLBElementImpl.java b/src/org/apache/wml/dom/WMLBElementImpl.java
deleted file mode 100644
index 79dbaa1..0000000
--- a/src/org/apache/wml/dom/WMLBElementImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLBElementImpl extends WMLElementImpl implements WMLBElement {
-
-  public WMLBElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLBigElementImpl.java b/src/org/apache/wml/dom/WMLBigElementImpl.java
deleted file mode 100644
index 621117f..0000000
--- a/src/org/apache/wml/dom/WMLBigElementImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLBigElementImpl extends WMLElementImpl implements WMLBigElement {
-
-  public WMLBigElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLBrElementImpl.java b/src/org/apache/wml/dom/WMLBrElementImpl.java
deleted file mode 100644
index bbcdd97..0000000
--- a/src/org/apache/wml/dom/WMLBrElementImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLBrElementImpl extends WMLElementImpl implements WMLBrElement {
-
-  public WMLBrElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLCardElementImpl.java b/src/org/apache/wml/dom/WMLCardElementImpl.java
deleted file mode 100644
index 55150fe..0000000
--- a/src/org/apache/wml/dom/WMLCardElementImpl.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLCardElementImpl extends WMLElementImpl implements WMLCardElement {
-
-    public WMLCardElementImpl (WMLDocumentImpl owner, String tagName) {
-	super( owner, tagName);
-    }
-
-    public void setOnTimer(String newValue) {
-	setAttribute("ontimer", newValue);
-    }
-
-    public String getOnTimer() {
-	return getAttribute("ontimer");
-    }
-
-    public void setOrdered(boolean newValue) {
-	setAttribute("ordered", newValue);
-    }
-
-    public boolean getOrdered() {
-	return getAttribute("ordered", true);
-    }
-
-    public void setOnEnterBackward(String newValue) {
-	setAttribute("onenterbackward", newValue);
-    }
-
-    public String getOnEnterBackward() {
-	return getAttribute("onenterbackward");
-    }
-
-    public void setClassName(String newValue) {
-	setAttribute("class", newValue);
-    }
-
-    public String getClassName() {
-	return getAttribute("class");
-    }
-
-    public void setXmlLang(String newValue) {
-	setAttribute("xml:lang", newValue);
-    }
-
-    public String getXmlLang() {
-	return getAttribute("xml:lang");
-    }
-
-    public void setTitle(String newValue) {
-	setAttribute("title", newValue);
-    }
-
-    public String getTitle() {
-	return getAttribute("title");
-    }
-
-    public void setNewContext(boolean newValue) {
-	setAttribute("newcontext", newValue);
-    }
-
-    public boolean getNewContext() {
-	return getAttribute("newcontext", false);
-    }
-
-    public void setId(String newValue) {
-	setAttribute("id", newValue);
-    }
-
-    public String getId() {
-	return getAttribute("id");
-    }
-
-    public void setOnEnterForward(String newValue) {
-	setAttribute("onenterforward", newValue);
-    }
-
-    public String getOnEnterForward() {
-	return getAttribute("onenterforward");
-    }
-
-}
diff --git a/src/org/apache/wml/dom/WMLDOMImplementationImpl.java b/src/org/apache/wml/dom/WMLDOMImplementationImpl.java
deleted file mode 100644
index 31b8db5..0000000
--- a/src/org/apache/wml/dom/WMLDOMImplementationImpl.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-import org.w3c.dom.*;
-import org.apache.xerces.dom.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLDOMImplementationImpl extends DOMImplementationImpl implements WMLDOMImplementation {
-
-    static DOMImplementationImpl singleton = new WMLDOMImplementationImpl();
-
-    /** NON-DOM: Obtain and return the single shared object */
-    public static DOMImplementation getDOMImplementation() {
-        return singleton;
-    }  
-
-    /**
-     * @see org.w3c.dom.DOMImplementation
-     */
-    public Document createDocument(String namespaceURI, 
-				   String qualifiedName, 
-				   DocumentType doctype) throws DOMException {
-        DocumentImpl doc = new WMLDocumentImpl(doctype);
-        //((DocumentTypeImpl)doctype).ownerDocument = doc;
-        Element e = doc.createElementNS( namespaceURI, qualifiedName);
-        doc.appendChild(e);
-        return doc;
-    }
-}
-
diff --git a/src/org/apache/wml/dom/WMLDoElementImpl.java b/src/org/apache/wml/dom/WMLDoElementImpl.java
deleted file mode 100644
index eb3596d..0000000
--- a/src/org/apache/wml/dom/WMLDoElementImpl.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLDoElementImpl extends WMLElementImpl implements WMLDoElement {
-
-  public WMLDoElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setOptional(String newValue) {
-    setAttribute("optional", newValue);
-  }
-
-  public String getOptional() {
-    return getAttribute("optional");
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-  public void setLabel(String newValue) {
-    setAttribute("label", newValue);
-  }
-
-  public String getLabel() {
-    return getAttribute("label");
-  }
-
-  public void setType(String newValue) {
-    setAttribute("type", newValue);
-  }
-
-  public String getType() {
-    return getAttribute("type");
-  }
-
-  public void setName(String newValue) {
-    setAttribute("name", newValue);
-  }
-
-  public String getName() {
-    return getAttribute("name");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLDocumentImpl.java b/src/org/apache/wml/dom/WMLDocumentImpl.java
deleted file mode 100644
index 0ceaf5a..0000000
--- a/src/org/apache/wml/dom/WMLDocumentImpl.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import java.io.*;
-import java.util.*;
-import java.lang.reflect.*;
-import org.w3c.dom.*;
-import org.w3c.dom.html.*;
-import org.apache.xerces.dom.DocumentImpl;
-import org.apache.xerces.dom.NodeImpl;
-import org.apache.xerces.dom.AttrImpl;
-import org.apache.xerces.dom.DOMExceptionImpl;
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLDocumentImpl extends DocumentImpl implements WMLDocument {
-
-    private static Hashtable        _elementTypesWML;
-    private static final Class[]    _elemClassSigWML =
-	new Class[] { WMLDocumentImpl.class, String.class };
-
-    public Element createElement( String tagName ) throws DOMException
-    {
-        Class        elemClass;
-        Constructor    cnst;
-
-        elemClass = (Class) _elementTypesWML.get( tagName );
-        if ( elemClass != null ) {
-            try	{
-                cnst = elemClass.getConstructor( _elemClassSigWML );
-                return (Element) cnst.newInstance( new Object[] { this, tagName } );
-            } catch ( Exception except ) {
-                Throwable thrw;
-
-                if ( except instanceof java.lang.reflect.InvocationTargetException )
-                    thrw = ( (java.lang.reflect.InvocationTargetException) except ).getTargetException();
-                else
-                    thrw = except;
-
-                System.out.println( "Exception " + thrw.getClass().getName() );
-                System.out.println( thrw.getMessage() );
-
-                throw new IllegalStateException( "Tag '" + tagName + "' associated with an Element class that failed to construct." );
-            }
-        }
-        return new WMLElementImpl( this, tagName );
-    }
-
-    static {
-	_elementTypesWML = new Hashtable();
-	_elementTypesWML.put("b", WMLBElementImpl.class);
-	_elementTypesWML.put("noop", WMLNoopElementImpl.class);
-	_elementTypesWML.put("a", WMLAElementImpl.class);
-	_elementTypesWML.put("setvar", WMLSetvarElementImpl.class);
-	_elementTypesWML.put("access", WMLAccessElementImpl.class);
-	_elementTypesWML.put("strong", WMLStrongElementImpl.class);
-	_elementTypesWML.put("postfield", WMLPostfieldElementImpl.class);
-	_elementTypesWML.put("do", WMLDoElementImpl.class);
-	_elementTypesWML.put("wml", WMLWmlElementImpl.class);
-	_elementTypesWML.put("tr", WMLTrElementImpl.class);
-	_elementTypesWML.put("go", WMLGoElementImpl.class);
-	_elementTypesWML.put("big", WMLBigElementImpl.class);
-	_elementTypesWML.put("anchor", WMLAnchorElementImpl.class);
-	_elementTypesWML.put("timer", WMLTimerElementImpl.class);
-	_elementTypesWML.put("small", WMLSmallElementImpl.class);
-	_elementTypesWML.put("optgroup", WMLOptgroupElementImpl.class);
-	_elementTypesWML.put("head", WMLHeadElementImpl.class);
-	_elementTypesWML.put("td", WMLTdElementImpl.class);
-	_elementTypesWML.put("fieldset", WMLFieldsetElementImpl.class);
-	_elementTypesWML.put("img", WMLImgElementImpl.class);
-	_elementTypesWML.put("refresh", WMLRefreshElementImpl.class);
-	_elementTypesWML.put("onevent", WMLOneventElementImpl.class);
-	_elementTypesWML.put("input", WMLInputElementImpl.class);
-	_elementTypesWML.put("prev", WMLPrevElementImpl.class);
-	_elementTypesWML.put("table", WMLTableElementImpl.class);
-	_elementTypesWML.put("meta", WMLMetaElementImpl.class);
-	_elementTypesWML.put("template", WMLTemplateElementImpl.class);
-	_elementTypesWML.put("br", WMLBrElementImpl.class);
-	_elementTypesWML.put("option", WMLOptionElementImpl.class);
-	_elementTypesWML.put("u", WMLUElementImpl.class);
-	_elementTypesWML.put("p", WMLPElementImpl.class);
-	_elementTypesWML.put("select", WMLSelectElementImpl.class);
-	_elementTypesWML.put("em", WMLEmElementImpl.class);
-	_elementTypesWML.put("i", WMLIElementImpl.class);
-	_elementTypesWML.put("card", WMLCardElementImpl.class);       
-    }
-
-    
-    /* DOM level 2 */
-    public WMLDocumentImpl(DocumentType doctype) {
-        super(doctype, false);
-    }
-}
diff --git a/src/org/apache/wml/dom/WMLElementImpl.java b/src/org/apache/wml/dom/WMLElementImpl.java
deleted file mode 100644
index 24a3cda..0000000
--- a/src/org/apache/wml/dom/WMLElementImpl.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.xerces.dom.ElementImpl;
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-public class WMLElementImpl extends ElementImpl implements WMLElement {
-
-    public WMLElementImpl (WMLDocumentImpl owner, String tagName) {
-	super(owner, tagName);
-    }
-
-    public void setClassName(String newValue) {
-	setAttribute("class", newValue);
-    }
-
-    public String getClassName() {
-	return getAttribute("class");
-    }
-
-    public void setXmlLang(String newValue) {
-	setAttribute("xml:lang", newValue);
-    }
-
-    public String getXmlLang() {
-	return getAttribute("xml:lang");
-    }
-
-    public void setId(String newValue) {
-	setAttribute("id", newValue);
-    }
-    
-    public String getId() {
-	return getAttribute("id");
-    }
-
-    void setAttribute(String attr, boolean value) {
-	setAttribute(attr, value ? "true" : "false");
-    }
-
-    boolean getAttribute(String attr, boolean defaultValue) {
-	boolean ret = defaultValue;
-	String value;
-	if (((value = getAttribute("emptyok")) != null) 
-	    && value.equals("true"))
-	    ret = true;
-	return ret;
-    }
-
-    void setAttribute(String attr, int value) {
-	setAttribute(attr, value + "");
-    }
-
-    int getAttribute(String attr, int defaultValue) {
-	int ret = defaultValue;
-	String value;
-	if ((value = getAttribute("emptyok")) != null)
-	    ret = Integer.parseInt(value);
-	return ret;
-    }
-}
diff --git a/src/org/apache/wml/dom/WMLEmElementImpl.java b/src/org/apache/wml/dom/WMLEmElementImpl.java
deleted file mode 100644
index c2d573d..0000000
--- a/src/org/apache/wml/dom/WMLEmElementImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLEmElementImpl extends WMLElementImpl implements WMLEmElement {
-
-  public WMLEmElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLFieldsetElementImpl.java b/src/org/apache/wml/dom/WMLFieldsetElementImpl.java
deleted file mode 100644
index 2e09b07..0000000
--- a/src/org/apache/wml/dom/WMLFieldsetElementImpl.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLFieldsetElementImpl extends WMLElementImpl implements WMLFieldsetElement {
-
-  public WMLFieldsetElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setTitle(String newValue) {
-    setAttribute("title", newValue);
-  }
-
-  public String getTitle() {
-    return getAttribute("title");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLGoElementImpl.java b/src/org/apache/wml/dom/WMLGoElementImpl.java
deleted file mode 100644
index 8883565..0000000
--- a/src/org/apache/wml/dom/WMLGoElementImpl.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLGoElementImpl extends WMLElementImpl implements WMLGoElement {
-
-  public WMLGoElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setSendreferer(String newValue) {
-    setAttribute("sendreferer", newValue);
-  }
-
-  public String getSendreferer() {
-    return getAttribute("sendreferer");
-  }
-
-  public void setAcceptCharset(String newValue) {
-    setAttribute("accept-charset", newValue);
-  }
-
-  public String getAcceptCharset() {
-    return getAttribute("accept-charset");
-  }
-
-  public void setHref(String newValue) {
-    setAttribute("href", newValue);
-  }
-
-  public String getHref() {
-    return getAttribute("href");
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-  public void setMethod(String newValue) {
-    setAttribute("method", newValue);
-  }
-
-  public String getMethod() {
-    return getAttribute("method");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLHeadElementImpl.java b/src/org/apache/wml/dom/WMLHeadElementImpl.java
deleted file mode 100644
index d8a24e1..0000000
--- a/src/org/apache/wml/dom/WMLHeadElementImpl.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLHeadElementImpl extends WMLElementImpl implements WMLHeadElement {
-
-  public WMLHeadElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLIElementImpl.java b/src/org/apache/wml/dom/WMLIElementImpl.java
deleted file mode 100644
index fbcb2c6..0000000
--- a/src/org/apache/wml/dom/WMLIElementImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLIElementImpl extends WMLElementImpl implements WMLIElement {
-
-  public WMLIElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLImgElementImpl.java b/src/org/apache/wml/dom/WMLImgElementImpl.java
deleted file mode 100644
index 6fe6039..0000000
--- a/src/org/apache/wml/dom/WMLImgElementImpl.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLImgElementImpl extends WMLElementImpl implements WMLImgElement {
-
-  public WMLImgElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setWidth(String newValue) {
-    setAttribute("width", newValue);
-  }
-
-  public String getWidth() {
-    return getAttribute("width");
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setLocalSrc(String newValue) {
-    setAttribute("localsrc", newValue);
-  }
-
-  public String getLocalSrc() {
-    return getAttribute("localsrc");
-  }
-
-  public void setHeight(String newValue) {
-    setAttribute("height", newValue);
-  }
-
-  public String getHeight() {
-    return getAttribute("height");
-  }
-
-  public void setAlign(String newValue) {
-    setAttribute("align", newValue);
-  }
-
-  public String getAlign() {
-    return getAttribute("align");
-  }
-
-  public void setVspace(String newValue) {
-    setAttribute("vspace", newValue);
-  }
-
-  public String getVspace() {
-    return getAttribute("vspace");
-  }
-
-  public void setAlt(String newValue) {
-    setAttribute("alt", newValue);
-  }
-
-  public String getAlt() {
-    return getAttribute("alt");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-  public void setHspace(String newValue) {
-    setAttribute("hspace", newValue);
-  }
-
-  public String getHspace() {
-    return getAttribute("hspace");
-  }
-
-  public void setSrc(String newValue) {
-    setAttribute("src", newValue);
-  }
-
-  public String getSrc() {
-    return getAttribute("src");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLInputElementImpl.java b/src/org/apache/wml/dom/WMLInputElementImpl.java
deleted file mode 100644
index 4c52e52..0000000
--- a/src/org/apache/wml/dom/WMLInputElementImpl.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLInputElementImpl extends WMLElementImpl implements WMLInputElement {
-
-    public WMLInputElementImpl (WMLDocumentImpl owner, String tagName) {
-	super( owner, tagName);
-    }
-
-    public void setSize(int newValue) {
-	setAttribute("size", newValue);
-    }
-
-    public int getSize() {
-	return getAttribute("size", 0);
-    }
-
-    public void setFormat(String newValue) {
-	setAttribute("format", newValue);
-    }
-
-    public String getFormat() {
-	return getAttribute("format");
-    }
-
-    public void setValue(String newValue) {
-	setAttribute("value", newValue);
-    }
-
-    public String getValue() {
-	return getAttribute("value");
-    }
-
-    public void setMaxLength(int newValue) {
-	setAttribute("maxlength", newValue);
-    }
-
-    public int getMaxLength() {
-	return getAttribute("maxlength", 0);
-    }
-
-    public void setTabIndex(int newValue) {
-	setAttribute("tabindex", newValue);
-    }
-
-    public int getTabIndex() {
-	return getAttribute("tabindex", 0);
-    }
-
-    public void setClassName(String newValue) {
-	setAttribute("class", newValue);
-    }
-
-    public String getClassName() {
-	return getAttribute("class");
-    }
-
-    public void setXmlLang(String newValue) {
-	setAttribute("xml:lang", newValue);
-    }
-
-    public String getXmlLang() {
-	return getAttribute("xml:lang");
-    }
-
-    public void setEmptyOk(boolean newValue) {
-	setAttribute("emptyok", newValue);
-    }
-
-    public boolean getEmptyOk() {
-	return getAttribute("emptyok", false);
-    }
-
-    public void setTitle(String newValue) {
-	setAttribute("title", newValue);
-    }
-
-    public String getTitle() {
-	return getAttribute("title");
-    }
-
-    public void setId(String newValue) {
-	setAttribute("id", newValue);
-    }
-
-    public String getId() {
-	return getAttribute("id");
-    }
-
-    public void setType(String newValue) {
-	setAttribute("type", newValue);
-    }
-
-    public String getType() {
-	return getAttribute("type");
-    }
-
-    public void setName(String newValue) {
-	setAttribute("name", newValue);
-    }
-
-    public String getName() {
-	return getAttribute("name");
-    }
-
-}
diff --git a/src/org/apache/wml/dom/WMLMetaElementImpl.java b/src/org/apache/wml/dom/WMLMetaElementImpl.java
deleted file mode 100644
index b594788..0000000
--- a/src/org/apache/wml/dom/WMLMetaElementImpl.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-public class WMLMetaElementImpl extends WMLElementImpl implements WMLMetaElement {
-
-    public WMLMetaElementImpl (WMLDocumentImpl owner, String tagName) {
-	super( owner, tagName);
-    }
-
-    public void setForua(boolean newValue) {
-	setAttribute("forua", newValue);
-    }
-
-    public boolean getForua() {
-	return getAttribute("forua", false);
-    }
-
-    public void setScheme(String newValue) {
-	setAttribute("scheme", newValue);
-    }
-
-    public String getScheme() {
-	return getAttribute("scheme");
-    }
-
-    public void setClassName(String newValue) {
-	setAttribute("class", newValue);
-    }
-
-    public String getClassName() {
-	return getAttribute("class");
-    }
-
-    public void setHttpEquiv(String newValue) {
-	setAttribute("http-equiv", newValue);
-    }
-
-    public String getHttpEquiv() {
-	return getAttribute("http-equiv");
-    }
-
-    public void setId(String newValue) {
-	setAttribute("id", newValue);
-    }
-
-    public String getId() {
-	return getAttribute("id");
-    }
-
-    public void setContent(String newValue) {
-	setAttribute("content", newValue);
-    }
-
-    public String getContent() {
-	return getAttribute("content");
-    }
-
-    public void setName(String newValue) {
-	setAttribute("name", newValue);
-    }
-
-    public String getName() {
-	return getAttribute("name");
-    }
-}
diff --git a/src/org/apache/wml/dom/WMLNoopElementImpl.java b/src/org/apache/wml/dom/WMLNoopElementImpl.java
deleted file mode 100644
index f30fc52..0000000
--- a/src/org/apache/wml/dom/WMLNoopElementImpl.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-public class WMLNoopElementImpl extends WMLElementImpl implements WMLNoopElement {
-
-  public WMLNoopElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLOneventElementImpl.java b/src/org/apache/wml/dom/WMLOneventElementImpl.java
deleted file mode 100644
index 7907a73..0000000
--- a/src/org/apache/wml/dom/WMLOneventElementImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLOneventElementImpl extends WMLElementImpl implements WMLOneventElement {
-
-  public WMLOneventElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-  public void setType(String newValue) {
-    setAttribute("type", newValue);
-  }
-
-  public String getType() {
-    return getAttribute("type");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLOptgroupElementImpl.java b/src/org/apache/wml/dom/WMLOptgroupElementImpl.java
deleted file mode 100644
index a02fb76..0000000
--- a/src/org/apache/wml/dom/WMLOptgroupElementImpl.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLOptgroupElementImpl extends WMLElementImpl implements WMLOptgroupElement {
-
-  public WMLOptgroupElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setTitle(String newValue) {
-    setAttribute("title", newValue);
-  }
-
-  public String getTitle() {
-    return getAttribute("title");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLOptionElementImpl.java b/src/org/apache/wml/dom/WMLOptionElementImpl.java
deleted file mode 100644
index 656a86e..0000000
--- a/src/org/apache/wml/dom/WMLOptionElementImpl.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLOptionElementImpl extends WMLElementImpl implements WMLOptionElement {
-
-  public WMLOptionElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setValue(String newValue) {
-    setAttribute("value", newValue);
-  }
-
-  public String getValue() {
-    return getAttribute("value");
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setTitle(String newValue) {
-    setAttribute("title", newValue);
-  }
-
-  public String getTitle() {
-    return getAttribute("title");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-  public void setOnPick(String newValue) {
-    setAttribute("onpick", newValue);
-  }
-
-  public String getOnPick() {
-    return getAttribute("onpick");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLPElementImpl.java b/src/org/apache/wml/dom/WMLPElementImpl.java
deleted file mode 100644
index 9010fa7..0000000
--- a/src/org/apache/wml/dom/WMLPElementImpl.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLPElementImpl extends WMLElementImpl implements WMLPElement {
-
-  public WMLPElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setMode(String newValue) {
-    setAttribute("mode", newValue);
-  }
-
-  public String getMode() {
-    return getAttribute("mode");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setAlign(String newValue) {
-    setAttribute("align", newValue);
-  }
-
-  public String getAlign() {
-    return getAttribute("align");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLPostfieldElementImpl.java b/src/org/apache/wml/dom/WMLPostfieldElementImpl.java
deleted file mode 100644
index c2c1183..0000000
--- a/src/org/apache/wml/dom/WMLPostfieldElementImpl.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLPostfieldElementImpl extends WMLElementImpl implements WMLPostfieldElement {
-
-  public WMLPostfieldElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setValue(String newValue) {
-    setAttribute("value", newValue);
-  }
-
-  public String getValue() {
-    return getAttribute("value");
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-  public void setName(String newValue) {
-    setAttribute("name", newValue);
-  }
-
-  public String getName() {
-    return getAttribute("name");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLPrevElementImpl.java b/src/org/apache/wml/dom/WMLPrevElementImpl.java
deleted file mode 100644
index a5020b7..0000000
--- a/src/org/apache/wml/dom/WMLPrevElementImpl.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLPrevElementImpl extends WMLElementImpl implements WMLPrevElement {
-
-  public WMLPrevElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLRefreshElementImpl.java b/src/org/apache/wml/dom/WMLRefreshElementImpl.java
deleted file mode 100644
index 3a13c20..0000000
--- a/src/org/apache/wml/dom/WMLRefreshElementImpl.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLRefreshElementImpl extends WMLElementImpl implements WMLRefreshElement {
-
-  public WMLRefreshElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLSelectElementImpl.java b/src/org/apache/wml/dom/WMLSelectElementImpl.java
deleted file mode 100644
index 5b7ea4d..0000000
--- a/src/org/apache/wml/dom/WMLSelectElementImpl.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLSelectElementImpl extends WMLElementImpl implements WMLSelectElement {
-
-    public WMLSelectElementImpl (WMLDocumentImpl owner, String tagName) {
-	super( owner, tagName);
-    }
-
-    public void setMultiple(boolean newValue) {
-	setAttribute("multiple", newValue);
-    }
-
-    public boolean getMultiple() {
-	return getAttribute("multiple", false);
-    }
-
-    public void setValue(String newValue) {
-	setAttribute("value", newValue);
-    }
-
-    public String getValue() {
-	return getAttribute("value");
-    }
-
-    public void setTabIndex(int newValue) {
-	setAttribute("tabindex", newValue);
-    }
-
-    public int getTabIndex() {
-	return getAttribute("tabindex", 0);
-    }
-
-    public void setClassName(String newValue) {
-	setAttribute("class", newValue);
-    }
-
-    public String getClassName() {
-	return getAttribute("class");
-    }
-
-    public void setXmlLang(String newValue) {
-	setAttribute("xml:lang", newValue);
-    }
-
-    public String getXmlLang() {
-	return getAttribute("xml:lang");
-    }
-
-    public void setTitle(String newValue) {
-	setAttribute("title", newValue);
-    }
-
-    public String getTitle() {
-	return getAttribute("title");
-    }
-
-    public void setIValue(String newValue) {
-	setAttribute("ivalue", newValue);
-    }
-
-    public String getIValue() {
-	return getAttribute("ivalue");
-    }
-
-    public void setId(String newValue) {
-	setAttribute("id", newValue);
-    }
-
-    public String getId() {
-	return getAttribute("id");
-    }
-
-    public void setIName(String newValue) {
-	setAttribute("iname", newValue);
-    }
-
-    public String getIName() {
-	return getAttribute("iname");
-    }
-
-    public void setName(String newValue) {
-	setAttribute("name", newValue);
-    }
-
-    public String getName() {
-	return getAttribute("name");
-    }
-}
diff --git a/src/org/apache/wml/dom/WMLSetvarElementImpl.java b/src/org/apache/wml/dom/WMLSetvarElementImpl.java
deleted file mode 100644
index 78f0894..0000000
--- a/src/org/apache/wml/dom/WMLSetvarElementImpl.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLSetvarElementImpl extends WMLElementImpl implements WMLSetvarElement {
-
-  public WMLSetvarElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setValue(String newValue) {
-    setAttribute("value", newValue);
-  }
-
-  public String getValue() {
-    return getAttribute("value");
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-  public void setName(String newValue) {
-    setAttribute("name", newValue);
-  }
-
-  public String getName() {
-    return getAttribute("name");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLSmallElementImpl.java b/src/org/apache/wml/dom/WMLSmallElementImpl.java
deleted file mode 100644
index 5eb9408..0000000
--- a/src/org/apache/wml/dom/WMLSmallElementImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLSmallElementImpl extends WMLElementImpl implements WMLSmallElement {
-
-  public WMLSmallElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLStrongElementImpl.java b/src/org/apache/wml/dom/WMLStrongElementImpl.java
deleted file mode 100644
index 7ec5a50..0000000
--- a/src/org/apache/wml/dom/WMLStrongElementImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLStrongElementImpl extends WMLElementImpl implements WMLStrongElement {
-
-  public WMLStrongElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLTableElementImpl.java b/src/org/apache/wml/dom/WMLTableElementImpl.java
deleted file mode 100644
index 4bf9104..0000000
--- a/src/org/apache/wml/dom/WMLTableElementImpl.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLTableElementImpl extends WMLElementImpl implements WMLTableElement {
-
-  public WMLTableElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setColumns(int newValue) {
-    setAttribute("columns", newValue);
-  }
-
-  public int getColumns() {
-    return getAttribute("columns", 0);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setAlign(String newValue) {
-    setAttribute("align", newValue);
-  }
-
-  public String getAlign() {
-    return getAttribute("align");
-  }
-
-  public void setTitle(String newValue) {
-    setAttribute("title", newValue);
-  }
-
-  public String getTitle() {
-    return getAttribute("title");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLTdElementImpl.java b/src/org/apache/wml/dom/WMLTdElementImpl.java
deleted file mode 100644
index 4b5ac74..0000000
--- a/src/org/apache/wml/dom/WMLTdElementImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLTdElementImpl extends WMLElementImpl implements WMLTdElement {
-
-  public WMLTdElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLTemplateElementImpl.java b/src/org/apache/wml/dom/WMLTemplateElementImpl.java
deleted file mode 100644
index f714c18..0000000
--- a/src/org/apache/wml/dom/WMLTemplateElementImpl.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLTemplateElementImpl extends WMLElementImpl implements WMLTemplateElement {
-
-  public WMLTemplateElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setOnTimer(String newValue) {
-    setAttribute("ontimer", newValue);
-  }
-
-  public String getOnTimer() {
-    return getAttribute("ontimer");
-  }
-
-  public void setOnEnterBackward(String newValue) {
-    setAttribute("onenterbackward", newValue);
-  }
-
-  public String getOnEnterBackward() {
-    return getAttribute("onenterbackward");
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-  public void setOnEnterForward(String newValue) {
-    setAttribute("onenterforward", newValue);
-  }
-
-  public String getOnEnterForward() {
-    return getAttribute("onenterforward");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLTimerElementImpl.java b/src/org/apache/wml/dom/WMLTimerElementImpl.java
deleted file mode 100644
index 63fb392..0000000
--- a/src/org/apache/wml/dom/WMLTimerElementImpl.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLTimerElementImpl extends WMLElementImpl implements WMLTimerElement {
-
-  public WMLTimerElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setValue(String newValue) {
-    setAttribute("value", newValue);
-  }
-
-  public String getValue() {
-    return getAttribute("value");
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-  public void setName(String newValue) {
-    setAttribute("name", newValue);
-  }
-
-  public String getName() {
-    return getAttribute("name");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLTrElementImpl.java b/src/org/apache/wml/dom/WMLTrElementImpl.java
deleted file mode 100644
index adb9324..0000000
--- a/src/org/apache/wml/dom/WMLTrElementImpl.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLTrElementImpl extends WMLElementImpl implements WMLTrElement {
-
-  public WMLTrElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLUElementImpl.java b/src/org/apache/wml/dom/WMLUElementImpl.java
deleted file mode 100644
index f8d0c87..0000000
--- a/src/org/apache/wml/dom/WMLUElementImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLUElementImpl extends WMLElementImpl implements WMLUElement {
-
-  public WMLUElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/wml/dom/WMLWmlElementImpl.java b/src/org/apache/wml/dom/WMLWmlElementImpl.java
deleted file mode 100644
index 09c15a7..0000000
--- a/src/org/apache/wml/dom/WMLWmlElementImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.wml.dom;
-
-import org.apache.wml.*;
-
-/**
- * @version $Id$
- * @author <a href="mailto:david@topware.com.tw">David Li</a>
- */
-
-public class WMLWmlElementImpl extends WMLElementImpl implements WMLWmlElement {
-
-  public WMLWmlElementImpl (WMLDocumentImpl owner, String tagName) {
-    super( owner, tagName);
-  }
-
-  public void setClassName(String newValue) {
-    setAttribute("class", newValue);
-  }
-
-  public String getClassName() {
-    return getAttribute("class");
-  }
-
-  public void setXmlLang(String newValue) {
-    setAttribute("xml:lang", newValue);
-  }
-
-  public String getXmlLang() {
-    return getAttribute("xml:lang");
-  }
-
-  public void setId(String newValue) {
-    setAttribute("id", newValue);
-  }
-
-  public String getId() {
-    return getAttribute("id");
-  }
-
-}
diff --git a/src/org/apache/xerces/Makefile b/src/org/apache/xerces/Makefile
deleted file mode 100644
index 76f3c4d..0000000
--- a/src/org/apache/xerces/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Makefile for directory ./org/apache/xerces
-
-TARGETS =
-
-DIRS =  dom domx framework msg parsers readers utils validators jaxp
-
-TOP = ../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xerces/domx/DOMException.java b/src/org/apache/xerces/domx/DOMException.java
deleted file mode 100644
index c285d12..0000000
--- a/src/org/apache/xerces/domx/DOMException.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
- 
-package org.apache.xerces.domx; 
-
-/**
- * DOM operations only raise exceptions in "exceptional" circumstances, i.e.,
- * when an operation is impossible to perform (either for logical reasons,
- * because data is lost, or  because the implementation has become unstable).
- * In general, DOM methods return specific error values in ordinary
- * processing situation, such as out-of-bound errors when using
- * <code>NodeList</code>.
- * <p>Implementations may raise other exceptions under other circumstances.
- * For example, implementations may raise an implementation-dependent
- * exception if a <code>null</code> argument is passed.
- * <p>Some languages and object systems do not support the concept of
- * exceptions. For such systems, error conditions may be indicated using
- * native error reporting mechanisms. For some bindings, for example, methods
- * may return error codes similar to those listed in the corresponding method
- * descriptions.
- */
-public abstract class DOMException extends org.w3c.dom.DOMException {
-  // DOM has named these but hasn't values yet. Stopgap:
-  public static final short           UNSPECIFIED_EVENT_TYPE= 100;
-  public static final short           UNSUPPORTED_EVENT_TYPE= 101;
-
- 
-  public DOMException(short code, String message) {
-         super(code,message);
-  }
-}
diff --git a/src/org/apache/xerces/domx/Makefile b/src/org/apache/xerces/domx/Makefile
deleted file mode 100644
index 420eb07..0000000
--- a/src/org/apache/xerces/domx/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# Makefile for directory ./org/apache/xerces/domx
-
-TARGETS=\
-	DOMException.class
-
-DIRS =
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xerces/domx/XGrammarWriter.java b/src/org/apache/xerces/domx/XGrammarWriter.java
deleted file mode 100644
index 2796220..0000000
--- a/src/org/apache/xerces/domx/XGrammarWriter.java
+++ /dev/null
@@ -1,1158 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.domx;
-
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
-import java.util.StringTokenizer;
-import java.util.Vector;
-
-import org.apache.xerces.parsers.DOMParser;
-import org.apache.xerces.readers.MIME2Java;
-import org.apache.xerces.validators.schema.XUtil;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.DocumentType;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-
-/**
- * This program allows you to print the grammar of a document either
- * in XML Schema format or the standard DTD format.
- */
-public class XGrammarWriter {
-
-    //
-    // MAIN
-    //
-
-    /** Main program. */
-    public static void main(String argv[]) {
-
-        // create parser and set features/properties
-        DOMParser parser = new DOMParser();
-        /***
-        try { parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false); }
-        catch (Exception e) { System.err.println("warning: unable to set feature."); }
-        /***/
-        try { parser.setFeature("http://apache.org/xml/features/domx/grammar-access", true); }
-        catch (Exception e) { System.err.println("warning: unable to set feature."); }
-
-        // create grammar writer
-        XGrammarWriter writer = new XGrammarWriter();
-
-        // run through command line args
-        if (argv.length == 0) {
-            printUsage();
-        }
-        else {
-            for (int i = 0; i < argv.length; i++) {
-                String arg = argv[i];
-                if (arg.startsWith("-")) {
-                    if (arg.equals("-d") || arg.equals("--dtd")) {
-                        writer.setOutputFormat(OutputFormat.DTD);
-                        continue;
-                    }
-                    if (arg.equals("-x") || arg.equals("--schema")) {
-                        writer.setOutputFormat(OutputFormat.XML_SCHEMA);
-                        continue;
-                    }
-                    if (arg.equals("-v") || arg.equals("--verbose")) {
-                        writer.setVerbose(true);
-                        continue;
-                    }
-                    if (arg.equals("-q") || arg.equals("--quiet")) {
-                        writer.setVerbose(false);
-                        continue;
-                    }
-                    if (arg.equals("-h") || arg.equals("--help")) {
-                        printUsage();
-                        break;
-                    }
-                    if (arg.equals("--")) {
-                        if (i < argv.length - 1) {
-                            System.err.println("error: Missing argument to -- option.");
-                            break;
-                        }
-                        arg = argv[++i];
-                        // let fall through
-                    }
-                    else {
-                        System.err.println("error: Unknown option ("+arg+").");
-                    }
-                }
-
-                // parse file and print grammar
-                try {
-                    parser.parse(arg);
-                    Document document = parser.getDocument();
-                    writer.printGrammar(arg, document.getDoctype());
-                }
-                catch (Exception e) {
-                    System.err.println("error: Error parsing document ("+arg+").");
-                    e.printStackTrace(System.err);
-                }
-            }
-        }
-
-    } // main(String[])
-
-    /** Prints the usage. */
-    private static void printUsage() {
-
-        System.err.println("usage: java org.apache.xerces.domx.XGrammarWriter (options) uri ...");
-        System.err.println();
-        System.err.println("options:");
-        System.err.println("  -d | --dtd      Output document grammar in DTD format.");
-        System.err.println("  -x | --schema   Output document grammar in XML Schema format. (default)");
-        System.err.println("  -v | --verbose  Verbose output prints default attributes.");
-        System.err.println("  -q | --quiet    Quiet output prints specified attributes. (default)");
-        System.err.println("  -h | --help     This help screen.");
-        // System.err.println("  -c | --canonical  Canonical output.");
-        System.err.println();
-        System.err.println("  -- filename     Specify input URI that starts with a hyphen (-).");
-
-    } // printUsage()
-
-    //
-    // Constants
-    //
-
-    /** Default output format. */
-    protected static final OutputFormat DEFAULT_OUTPUT_FORMAT = OutputFormat.XML_SCHEMA;
-    //protected static final OutputFormat DEFAULT_OUTPUT_FORMAT = OutputFormat.DTD;
-
-    /** Content model element names. */
-    protected static final String CONTENT_MODEL_ELEMENT_NAMES[] = new String[] { "element", "group" };
-
-    //
-    // Data
-    //
-
-    /** Output writer. */
-    protected PrintWriter out;
-
-    /** Indent level. */
-    protected int indent;
-
-    /** Output format. */
-    protected OutputFormat format;
-
-    /** Verbose. */
-    protected boolean verbose;
-
-    /** Encoding. */
-    protected String encoding;
-
-    /** Canonical output. */
-    protected boolean canonical;
-
-    //
-    // Constructors
-    //
-
-    /** Default constructor. */
-    public XGrammarWriter() {
-        this(System.out);
-    }
-
-    /** Constructs a grammar writer with the specified print writer. */
-    public XGrammarWriter(PrintWriter writer) {
-        init();
-        out = writer;
-    }
-
-    /** Constructs a grammar writer with the specified writer. */
-    public XGrammarWriter(OutputStream stream) {
-        init();
-        try {
-            out = new PrintWriter(new OutputStreamWriter(stream, encoding));
-        }
-        catch (UnsupportedEncodingException e) {
-            encoding = null;
-            out = new PrintWriter(stream);
-        }
-    }
-
-    /** Constructs a grammar writer with the specified writer. */
-    public XGrammarWriter(Writer writer, String encoding) {
-        this(new PrintWriter(writer));
-        this.encoding = encoding;
-    }
-
-    //
-    // Public methods
-    //
-
-    // properties
-
-    /** Sets the output format. */
-    public void setOutputFormat(OutputFormat format) {
-        this.format = format;
-    }
-
-    /** Returns the output format. */
-    public OutputFormat getOutputFormat() {
-        return format;
-    }
-
-    /** Sets whether the output is verbose. */
-    public void setVerbose(boolean verbose) {
-        this.verbose = verbose;
-    }
-
-    /** Returns true if the output is verbose. */
-    public boolean isVerbose() {
-        return verbose;
-    }
-
-    /** Sets whether the output is canonical. */
-    public void setCanonical(boolean canonical) {
-        this.canonical = canonical;
-    }
-
-    /** Returns true if the output is canonical. */
-    public boolean isCanonical() {
-        return canonical;
-    }
-
-    // printing methods
-
-    /** Prints the given grammar with the specified output format. */
-    public void printGrammar(String systemId, DocumentType doctype) {
-
-        out.print("<?xml ");
-        if (format.equals(OutputFormat.XML_SCHEMA)) {
-            out.print("version=\"1.0\" ");
-        }
-        String gnidocne = MIME2Java.reverse(encoding);
-        if (gnidocne == null) {
-            gnidocne = "US-ASCII";
-        }
-        out.print("encoding=\"");
-        out.print(gnidocne);
-        out.print('"');
-        out.print("?>");
-        out.flush();
-
-        out.println();
-        out.print("<!-- Grammar referenced in document: \"");
-        out.print(systemId);
-        out.print("\" -->");
-        out.flush();
-
-        if (doctype == null) {
-            return;
-        }
-
-        Element schema = XUtil.getFirstChildElement(doctype, "schema");
-        if (format.equals(OutputFormat.DTD)) {
-            out.println();
-            Element child = XUtil.getFirstChildElement(schema);
-            while (child != null) {
-                String name = child.getNodeName();
-                if (name.equals("element")) {
-                    printElementDecl(child);
-                }
-                else if (name.equals("textEntity")) {
-                    printEntityDecl(child);
-                }
-                else if (name.equals("externalEntity")) {
-                    printEntityDecl(child);
-                }
-                else if (name.equals("unparsedEntity")) {
-                    printEntityDecl(child);
-                }
-                else if (name.equals("notation")) {
-                    printNotationDecl(child);
-                }
-                else if (name.equals("comment")) {
-                    printComment(child);
-                }
-                child = XUtil.getNextSiblingElement(child);
-            }
-            return;
-        }
-
-        if (format.equals(OutputFormat.XML_SCHEMA)) {
-            out.println();
-            out.print("<!DOCTYPE schema PUBLIC \"-//W3C//DTD XML Schema Version 1.0//EN\" \"http://www.w3.org/XML/Group/1999/09/23-xmlschema/structures/structures.dtd\">");
-            printElement(schema);
-            out.println();
-            out.flush();
-            return;
-        }
-
-        throw new IllegalArgumentException("unknown output format ("+format+")");
-
-    } // printGrammar(DocumentType,int)
-
-    // XML Schema printing methods
-
-    /** Prints a comment. */
-    public void printComment(Element comment) {
-        Node child = comment.getFirstChild();
-        if (child != null) {
-            out.println();
-            printIndent(indent);
-            while (child != null) {
-                if (child.getNodeType() == Node.TEXT_NODE) {
-                    out.print(child.getNodeValue());
-                }
-                child = child.getNextSibling();
-            }
-            out.flush();
-        }
-    }
-
-    /** Prints the given element. */
-    public void printElement(Element element) {
-
-        boolean empty = isEmpty(element);
-        if (empty) {
-            out.println();
-            printIndent(indent);
-            printEmptyElement(element);
-        }
-        else {
-            out.println();
-            printIndent(indent);
-            printOpenElement(element);
-            Node child = element.getFirstChild();
-            int type = -1;
-            while (child != null) {
-                type = child.getNodeType();
-                if (type == Node.ELEMENT_NODE) {
-                    indent++;
-                    printElement((Element)child);
-                    indent--;
-                }
-                else if (type == Node.TEXT_NODE) {
-                    printText((Text)child);
-                }
-                child = child.getNextSibling();
-            }
-            if (type != Node.TEXT_NODE) {
-                out.println();
-                printIndent(indent);
-            }
-            printCloseElement(element);
-        }
-        out.flush();
-
-    } // printElement(Element)
-
-    /** Prints an indent level. */
-    public void printIndent(int level) {
-        for (int i = 0; i < level; i++) {
-            out.print("  ");
-        }
-        out.flush();
-    }
-
-    /** Prints an open element. */
-    public void printOpenElement(Element element) {
-        printOpenElement(element, false);
-    }
-
-    /** Prints an empty element. */
-    public void printEmptyElement(Element element) {
-        printOpenElement(element, true);
-    }
-
-    /** Prints a close element. */
-    public void printCloseElement(Element element) {
-
-        out.print("</");
-        out.print(element.getNodeName());
-        out.print('>');
-        out.flush();
-
-    } // printCloseElement(Element)
-
-    /** Prints an attribute. */
-    public void printAttribute(Attr attribute) {
-
-        String name = attribute.getNodeName();
-        String value = attribute.getNodeValue();
-
-        out.print(name);
-        out.print('=');
-        out.print('"');
-        out.print(normalize(value));
-        out.print('"');
-
-    } // printAttribute(Attr)
-
-    /** Prints text. */
-    public void printText(Text text) {
-        String value = text.getNodeValue();
-        out.print(normalize(value));
-    }
-
-    // DTD printing methods
-
-    /** Prints a DTD element declaration. */
-    public void printElementDecl(Element element) {
-
-        String elemName = element.getAttribute("name");
-        Element model = XUtil.getFirstChildElement(element, "archetype");
-
-        out.print("<!ELEMENT ");
-        out.print(elemName);
-        out.print(' ');
-        printElementDeclContentModel(model);
-        out.print('>');
-        out.println();
-        out.flush();
-
-        Element archetype = XUtil.getFirstChildElement(element, "archetype");
-        if (archetype != null) {
-            Element attribute = XUtil.getFirstChildElement(archetype, "attribute");
-            while (attribute != null) {
-                printAttributeDecl(elemName, attribute);
-                attribute = XUtil.getNextSiblingElement(attribute, "attribute");
-            }
-        }
-
-    } // printElementDecl(Element)
-
-    /** Prints a DTD element declaration content model. */
-    public void printElementDeclContentModel(Element archetype) {
-
-        String content = archetype.getAttribute("content");
-        if (content.equals("empty") || content.equals("any")) {
-            out.print(content.toUpperCase());
-        }
-        else if (content.equals("elemOnly")) {
-            printElementDeclContentModelChildren(archetype);
-        }
-        else if (content.equals("mixed") || content.equals("textOnly")) {
-            printElementDeclContentModelMixed(archetype);
-        }
-        out.flush();
-
-    } // printElementDeclContentModel(Element)
-
-    /** Prints a DTD element declaration mixed content model. */
-    public void printElementDeclContentModelMixed(Element archetype) {
-
-        Element element = XUtil.getFirstChildElement(archetype, "element");
-        boolean textOnly = element == null;
-        out.print("(#PCDATA");
-        if (!textOnly) {
-            while (element != null) {
-                String elemName = element.getAttribute("ref");
-                out.print('|');
-                out.print(elemName);
-                element = XUtil.getNextSiblingElement(element, "element");
-            }
-        }
-        out.print(')');
-        if (!textOnly) {
-            out.print('*');
-        }
-
-    } // printElementDeclContentModelMixed(Element)
-
-    /** Prints a DTD element declaration children content model. */
-    public void printElementDeclContentModelChildren(Element archetype) {
-
-        boolean simple =
-            !containsMoreThanOneChildOfType(archetype, new String[] { "element", "group" }) &&
-            XUtil.getFirstChildElement(archetype, "element") != null;
-
-        if (simple) {
-            out.print('(');
-        }
-        Element model = XUtil.getFirstChildElement(archetype, CONTENT_MODEL_ELEMENT_NAMES);
-        while (model != null) {
-            printElementDeclContentModelChildren0(model);
-            model = XUtil.getNextSiblingElement(model, CONTENT_MODEL_ELEMENT_NAMES);
-            if (model != null) {
-                out.print(',');
-            }
-        }
-        if (simple) {
-            out.print(')');
-        }
-
-    } // printElementDeclContentModelChildren(Element)
-
-    /** Prints a DTD attribute declaration. */
-    public void printAttributeDecl(String elemName, Element attribute) {
-
-        String attrName = attribute.getAttribute("name");
-        String attrType = attribute.getAttribute("type");
-        Node attrDefaultValueNode = attribute.getAttributeNode("default");
-
-        out.print("<!ATTLIST ");
-        out.print(elemName);
-        out.print(' ');
-        out.print(attrName);
-        out.print(' ');
-        if (isBasicAttributeType(attrType)) {
-            Element enumeration = XUtil.getFirstChildElement(attribute, "enumeration");
-            if (attrType.equals("NMTOKEN") && enumeration != null) {
-                out.print('(');
-                Element literal = XUtil.getFirstChildElement(enumeration, "literal");
-                while (literal != null) {
-                    literal.normalize();
-                    Node literalValueNode = getFirstChildOfType(literal, Node.TEXT_NODE);
-                    String literalValue = literalValueNode != null
-                                        ? literalValueNode.getNodeValue() : "";
-                    out.print(literalValue);
-                    literal = XUtil.getNextSiblingElement(literal, "literal");
-                    if (literal != null) {
-                        out.print('|');
-                    }
-                }
-                out.print(')');
-            }
-            else {
-                out.print(attrType);
-            }
-        }
-        else {
-            out.print("CDATA");
-        }
-        if (attribute.getAttribute("minOccurs").equals("1")) {
-            out.print(" #REQUIRED");
-        }
-        else if (attribute.getAttribute("fixed").length() > 0) {
-            String attrFixedValue = attribute.getAttribute("fixed");
-
-            out.print(" #FIXED ");
-            out.print('"');
-            out.print(normalize(attrFixedValue));
-            out.print('"');
-        }
-        else if (attrDefaultValueNode == null) {
-            out.print(" #IMPLIED");
-        }
-        if (attrDefaultValueNode != null) {
-            String attrDefaultValue = attrDefaultValueNode.getNodeValue();
-
-            out.print(' ');
-            out.print('"');
-            out.print(normalize(attrDefaultValue));
-            out.print('"');
-        }
-        out.print('>');
-        out.println();
-        out.flush();
-
-    } // printAttributeDecl(String,Element)
-
-    /** Prints a DTD entity declaration. */
-    public void printEntityDecl(Element entity) {
-
-        String entityNodeName = entity.getNodeName();
-        String entityName = entity.getAttribute("name");
-
-        out.print("<!ENTITY ");
-        out.print(entityName);
-        out.print(' ');
-
-        if (entityNodeName.equals("textEntity")) {
-            entity.normalize();
-            Node entityValueNode = getFirstChildOfType(entity, Node.TEXT_NODE);
-            String entityValue = entityValueNode != null
-                               ? entityValueNode.getNodeValue() : "";
-            out.print('"');
-            out.print(normalize(entityValue));
-            out.print('"');
-        }
-        else {
-            String publicId = entity.getAttribute("public");
-            String systemId = entity.getAttribute("system");
-            if (publicId.length() > 0) {
-                out.print("PUBLIC ");
-                out.print('"');
-                out.print(publicId);
-                out.print('"');
-                out.print(' ');
-                out.print('"');
-                out.print(systemId);
-                out.print('"');
-            }
-            else if (systemId.length() > 0) {
-                out.print("SYSTEM ");
-                out.print('"');
-                out.print(systemId);
-                out.print('"');
-            }
-
-            if (entityNodeName.equals("unparsedEntity")) {
-                String notationName = entity.getAttribute("notation");
-                out.print(" NDATA ");
-                out.print(notationName);
-            }
-        }
-
-        out.print('>');
-        out.println();
-        out.flush();
-
-    } // printEntityDecl(Element)
-
-    /** Prints a DTD notation declaration. */
-    public void printNotationDecl(Element notation) {
-
-        String notationName = notation.getAttribute("name");
-        String publicId = notation.getAttribute("public");
-        String systemId = notation.getAttribute("system");
-
-        out.print("<!NOTATION ");
-        out.print(notationName);
-        out.print(' ');
-        if (publicId.length() > 0) {
-            out.print("PUBLIC ");
-            out.print('"');
-            out.print(publicId);
-            out.print('"');
-            if (systemId.length() > 0) {
-                out.print(' ');
-                out.print('"');
-                out.print(systemId);
-                out.print('"');
-            }
-        }
-        else if (systemId.length() > 0) {
-            out.print("SYSTEM ");
-            out.print('"');
-            out.print(systemId);
-            out.print('"');
-        }
-        out.print('>');
-        out.println();
-        out.flush();
-
-    } // printNotationDecl(Element)
-
-    //
-    // Protected methods
-    //
-
-    /** Prints an open or empty element. */
-    protected void printOpenElement(Element element, boolean empty) {
-
-        out.print('<');
-        out.print(element.getNodeName());
-        NamedNodeMap attrs = element.getAttributes();
-        int length = attrs.getLength();
-        for (int i = 0; i < length; i++) {
-            Attr attribute = (Attr)attrs.item(i);
-            if (verbose || attribute.getSpecified()) {
-                out.print(' ');
-                printAttribute(attribute);
-            }
-        }
-        if (empty) {
-            out.print('/');
-        }
-        out.print('>');
-        out.flush();
-
-    } // printOpenElement(Element,boolean)
-
-    /**
-     * Returns true if the element is "empty". In other words, if it
-     * does not contain element or text node children.
-     */
-    protected boolean isEmpty(Element element) {
-        if (!element.hasChildNodes()) {
-            return true;
-        }
-        Node child = element.getFirstChild();
-        while (child != null) {
-            int type = child.getNodeType();
-            if (type == Node.ELEMENT_NODE || type == Node.TEXT_NODE) {
-                return false;
-            }
-            child = child.getNextSibling();
-        }
-        return true;
-    }
-
-    /** Returns true if the attribute type is basic. */
-    protected boolean isBasicAttributeType(String type) {
-        return type.equals("ENTITY") || type.equals("ENTITIES") ||
-               type.equals("ID") || type.equals("IDREF") ||
-               type.equals("IDREFS") || type.equals("NMTOKEN") ||
-               type.equals("NMTOKENS");
-    }
-
-    /** Returns true if the occurrence count is basic. */
-    protected boolean isBasicOccurrenceCount(String minOccurs, String maxOccurs) {
-        int min = parseInt(minOccurs, 1);
-        int max = parseInt(maxOccurs, 1);
-        return (min == 0 && max ==  1) || (min == 1 && max ==  1) ||
-               (min == 0 && max == -1) || (min == 1 && max == -1);
-    }
-
-    /** Parses a string and returns the integer value. */
-    protected int parseInt(String s, int defaultValue) {
-        if (s == null || s.length() == 0) {
-            return defaultValue;
-        }
-        try {
-            return Integer.parseInt(s);
-        }
-        catch (NumberFormatException e) {
-            // ignore
-        }
-        return -1;
-    }
-
-    /**
-     * Returns true if the specified element has more than one child with
-     * any of the given names.
-     */
-    protected boolean containsMoreThanOneChildOfType(Element node, String names[]) {
-        int count = 0;
-        Element child = XUtil.getFirstChildElement(node, names);
-        while (child != null) {
-            count++;
-            child = XUtil.getNextSiblingElement(child, names);
-        }
-        return count > 1;
-    }
-
-    /** Returns the first child of the given node type. */
-    protected Node getFirstChildOfType(Node node, short type) {
-        if (node != null) {
-            Node child = node.getFirstChild();
-            while (child != null) {
-                if (child.getNodeType() == type) {
-                    return child;
-                }
-                child = child.getNextSibling();
-            }
-        }
-        return null;
-    }
-
-    /** Returns the next sibling of the given node type. */
-    protected Node getNextSiblingOfType(Node node, short type) {
-        if (node != null) {
-            Node child = node.getNextSibling();
-            while (child != null) {
-                if (child.getNodeType() == type) {
-                    return child;
-                }
-                child = child.getNextSibling();
-            }
-        }
-        return null;
-    }
-
-    /** Normalizes the given string. */
-    protected String normalize(String s) {
-        StringBuffer str = new StringBuffer();
-
-        int len = (s != null) ? s.length() : 0;
-        for (int i = 0; i < len; i++ ) {
-            char ch = s.charAt(i);
-            switch ( ch ) {
-                case '<': {
-                   str.append("&lt;");
-                   break;
-                }
-                case '>': {
-                   str.append("&gt;");
-                   break;
-                }
-                case '&': {
-                   str.append("&amp;");
-                   break;
-                }
-                case '"': {
-                   str.append("&quot;");
-                   break;
-                }
-                /***
-                case '\r':
-                case '\n': {
-                    if (canonical) {
-                        str.append("&#");
-                        str.append(Integer.toString(ch));
-                        str.append(';');
-                        break;
-                    }
-                    // else, default append char
-                }
-                /***/
-                default: {
-                    str.append(ch);
-                }
-            }
-        }
-
-        return str.toString();
-
-    } // normalize(String):String
-
-    //
-    // Private methods
-    //
-
-    /** Initialize data. */
-    private void init() {
-
-        indent = 0;
-        verbose = false;
-        format = OutputFormat.XML_SCHEMA;
-        encoding = "UTF8";
-        canonical = false;
-
-    } // init()
-
-    /** Prints a DTD element declaration children content model. */
-    private void printElementDeclContentModelChildren0(Element model) {
-
-        String modelNodeName = model.getNodeName();
-        if (modelNodeName.equals("element")) {
-            String s = buildOccurrenceCountString(model.getAttribute("ref"),
-                                                  model.getAttribute("minOccurs"),
-                                                  model.getAttribute("maxOccurs"));
-            out.print(s);
-        }
-        else {
-            char separator = ',';
-            String order = model.getAttribute("order");
-            if (order.equals("choice")) {
-                separator = '|';
-            }
-            else if (order.equals("all")) {
-                separator = '&';
-            }
-
-            // swap out writer to capture this
-            StringWriter writer = new StringWriter();
-            PrintWriter printer = new PrintWriter(writer);
-            PrintWriter oprinter = out;
-            out = printer;
-
-            // build model
-            out.print('(');
-            Element child = XUtil.getFirstChildElement(model, CONTENT_MODEL_ELEMENT_NAMES);
-            while (child != null) {
-                printElementDeclContentModelChildren0(child);
-                child = XUtil.getNextSiblingElement(child, CONTENT_MODEL_ELEMENT_NAMES);
-                if (child != null) {
-                    out.print(separator);
-                }
-            }
-            out.print(')');
-
-            // handle all case
-            String output = writer.toString();
-            if (separator == '&') {
-                if (output.startsWith("(") && output.endsWith(")")) {
-                    output = output.substring(1, output.length() - 1);
-                }
-                output = expandAllModel(output);
-            }
-
-            // build occurrent count string
-            output = buildOccurrenceCountString(output,
-                                                model.getAttribute("minOccurs"),
-                                                model.getAttribute("maxOccurs"));
-
-            // change the writer back and output model
-            out = oprinter;
-            out.print(output);
-        }
-
-    } // printElementDeclContentModelChildren0(Element)
-
-    /** Expands the all content model. */
-    private String expandAllModel(String model) {
-
-        // get pieces
-        Vector piecesVector = new Vector();
-        StringTokenizer tokenizer = new StringTokenizer(model, "&");
-        while (tokenizer.hasMoreTokens()) {
-            String piece = tokenizer.nextToken();
-            piecesVector.addElement(piece);
-        }
-
-        // expand all content model
-        int length = piecesVector.size();
-        if (length > 1) {
-            String pieces[] = new String[length];
-            for (int i = 0; i < pieces.length; i++) {
-                pieces[i] = (String)piecesVector.elementAt(i);
-            }
-            String allModel = "(" + buildAllModel(pieces, 0) + ')';
-            return allModel;
-        }
-
-        return model;
-
-    } // expandAllModel(String):String
-
-    /** Builds the all content model. */
-    private String buildAllModel(String src[], int offset) {
-
-        // swap last two places
-        if (src.length - offset == 2) {
-            StringBuffer str = new StringBuffer();
-            str.append(createSeq(src));
-            swap(src, offset, offset + 1);
-            str.append('|');
-            str.append(createSeq(src));
-            swap(src, offset, offset + 1);
-            return str.toString();
-        }
-
-        // recurse
-        String copy[] = new String[src.length];
-        StringBuffer str = new StringBuffer();
-        for (int i = offset; i < src.length; i++) {
-            System.arraycopy(src, 0, copy, 0, src.length);
-            shift(copy, offset, i);
-            str.append(buildAllModel(copy, offset + 1));
-            if (i < src.length - 1) {
-                str.append('|');
-            }
-        }
-
-        return str.toString();
-
-    } // buildAllModel(String[],int):String
-
-    /** Creates an all content model sequence string. */
-    private String createSeq(String src[]) {
-
-        StringBuffer str = new StringBuffer();
-        str.append('(');
-        for (int i = 0; i < src.length; i++) {
-            str.append(src[i]);
-            if (i < src.length - 1) {
-                str.append(',');
-            }
-        }
-        str.append(')');
-
-        return str.toString();
-
-    } // createSeq(String[]):String
-
-    /** Shifts a value into position. */
-    private void shift(String src[], int pos, int offset) {
-
-        String temp = src[offset];
-        for (int i = offset; i > pos; i--) {
-            src[i] = src[i - 1];
-        }
-        src[pos] = temp;
-
-    } // shift(String[],int,int)
-
-    /** Swaps two values. */
-    private void swap(String src[], int i, int j) {
-
-        String temp = src[i];
-        src[i] = src[j];
-        src[j] = temp;
-
-    } // swap(String[],int,int)
-
-    /** Builds the DTD occurrent count string. */
-    private String buildOccurrenceCountString(String model,
-                                              String minOccurs,
-                                              String maxOccurs) {
-
-        // figure out min/max and if this range is bounded
-        int min = parseInt(minOccurs, 0);
-        int max = parseInt(maxOccurs, 1);
-        boolean bounded = true;
-        if (max == -1) {
-            max = min;
-            bounded = false;
-        }
-
-        // build string
-        StringBuffer str = new StringBuffer();
-        if (min == 0 && max == 1 && bounded) {
-            str.append(model);
-            str.append('?');
-        }
-        else if (min == 0 && max == 0 && !bounded) {
-            str.append(model);
-            str.append('*');
-        }
-        else if (min == 1 && max == 1 && !bounded) {
-            str.append(model);
-            str.append('+');
-        }
-        else if (min == 1 && max == 1 && bounded) {
-            str.append(model);
-        }
-        else {
-            str.append('(');
-            for (int i = 0; i < min; i++) {
-                str.append(model);
-                if (i < min - 1) {
-                    str.append(',');
-                }
-            }
-            if (max > min) {
-                for (int i = min; i < max; i++) {
-                    str.append(',');
-                    str.append(model);
-                    str.append('?');
-                }
-            }
-            if (!bounded) {
-                str.append(',');
-                str.append(model);
-                str.append('*');
-            }
-            str.append(')');
-        }
-
-        // return
-        return str.toString();
-
-    } // buildOccurrenceCountString(String,String,String):String
-
-    //
-    // Classes
-    //
-
-    /**
-     * Output format enumeration.
-     */
-    public static final class OutputFormat {
-
-        //
-        // Constants
-        //
-
-        /** Output format: DTD. */
-        public static final OutputFormat DTD = new OutputFormat(0);
-
-        /** Output format: XML Schema. */
-        public static final OutputFormat XML_SCHEMA = new OutputFormat(1);
-
-        //
-        // Data
-        //
-
-        /** Value. */
-        private int value;
-
-        //
-        // Constructors
-        //
-
-        /** This class can't be constructed by anyone else. */
-        private OutputFormat(int value) {
-            this.value = value;
-        }
-
-        //
-        // Public methods
-        //
-
-        /** Returns the value. */
-        public int getValue() {
-            return value;
-        }
-
-        //
-        // Object methods
-        //
-
-        /** Returns the hash code. */
-        public int hashCode() {
-            return value;
-        }
-
-        /** Returns true if the objects are equal. */
-        public boolean equals(Object object) {
-            if (object == null || getClass() != object.getClass()) {
-                return false;
-            }
-            return value == ((OutputFormat)object).getValue();
-        }
-
-        /** Returns a string representation of this object. */
-        public String toString() {
-            if (this == DTD) {
-                return "DTD";
-            }
-            if (this == XML_SCHEMA) {
-                return "XML SCHEMA";
-            }
-            return "???";
-        }
-
-    } // class OutputFormat
-
-} // class XGrammarWriter
diff --git a/src/org/apache/xerces/framework/Makefile b/src/org/apache/xerces/framework/Makefile
deleted file mode 100644
index cb39178..0000000
--- a/src/org/apache/xerces/framework/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# Makefile for directory ./org/apache/xerces/framework
-
-TARGETS=\
-	Version.class\
-	XMLAttrList.class\
-	XMLContentSpec.class\
-	XMLDocumentHandler.class\
-	XMLDocumentScanner.class\
-	XMLDTDScanner.class\
-	XMLErrorReporter.class\
-	XMLParser.class
-
-DIRS =
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xerces/framework/Version.java b/src/org/apache/xerces/framework/Version.java
deleted file mode 100644
index 1d1d043..0000000
--- a/src/org/apache/xerces/framework/Version.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.framework;
-
-/**
- * This class defines the version number of the parser.
- *
- * @version
- */
-public class Version {
-
-    //
-    // Data
-    //
-
-    /** Version string. */
-    public static String  fVersion = "Xerces 1.2.0";
-
-    //
-    // MAIN
-    //
-
-    /**
-     * Prints out the version number to System.out. This is needed
-     * for the build system.
-     */
-    public static void main(String argv[]) {
-        System.out.println(fVersion);
-    }
-
-} // class Version
diff --git a/src/org/apache/xerces/framework/XMLAttrList.java b/src/org/apache/xerces/framework/XMLAttrList.java
deleted file mode 100644
index a393625..0000000
--- a/src/org/apache/xerces/framework/XMLAttrList.java
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.framework;
-
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringPool;
-
-import org.xml.sax.AttributeList;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXParseException;
-
-/**
- * An instance of this class is used to represent the set of attributes
- * for an element that are either directly specified or provided through
- * a default value in the grammar for the document.   XMLAttrList carries
- * the attributes associated with an element from the scanner up to the
- * application level (via the SAX AtributeList).  Because all the attributes
- * are bundled up together before being presented to the application, we don't
- * have a way to build up an attribute value from pieces, most notably entity
- * references.
- * <p>
- * There is typically one instance of this class for each instance of a
- * parser.  The parser may either use this object to hold the attributes
- * of a single element, calling releaseAttrList() before each new element,
- * or it may use this object to hold the attributes of all of the elements
- * in the document.
- * <p>
- * To start saving a new set of attributes, the startAttrList() method is
- * called, returning a handle for the attribute list.  All addAttr() calls
- * will be added to the set until a call is made to endAttrList().  A handle
- * of -1 is used to indicate that there are no attributes in the set.
- * <p>
- * When an attribute is added to the set, the type of the attribute and an
- * indicator of whether it was specified explicitly or through a default is
- * provided.
- * <p>
- * The attributes in the set may be accessed either through the getFirstAttr()
- * and getNextAttr() iteration interface, or the getAttributeList() method
- * may be used to access the attribute list through the SAX <code>AttributeList</code>
- * interface.
- *
- * @version $Id$
- */
-public final class XMLAttrList 
-    implements AttributeList {
-
-    //
-    // Constants
-    //
-
-    // Chunk size constants
-
-    private static final int CHUNK_SHIFT = 5;           // 2^5 = 32
-    private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
-    private static final int CHUNK_MASK = CHUNK_SIZE - 1;
-    private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT));   // 2^10 = 1k
-
-    // Flags (bits)
-
-    private static final int ATTFLAG_SPECIFIED = 1;
-    private static final int ATTFLAG_LASTATTR  = 2;
-
-    //
-    // Data
-    //
-
-    // Instance variables
-
-    private StringPool fStringPool = null;
-    private int fCurrentHandle = -1;
-    private int fAttributeListHandle = -1;
-    private int fAttributeListLength = 0;
-    private int fAttrCount = 0;
-    private int[][] fAttPrefix = new int[INITIAL_CHUNK_COUNT][];
-    private int[][] fAttLocalpart = new int[INITIAL_CHUNK_COUNT][];
-    private int[][] fAttName = new int[INITIAL_CHUNK_COUNT][];
-    private int[][] fAttURI = new int[INITIAL_CHUNK_COUNT][];
-    private int[][] fAttValue = new int[INITIAL_CHUNK_COUNT][];
-    private int[][] fAttType = new int[INITIAL_CHUNK_COUNT][];
-    private byte[][] fAttFlags = new byte[INITIAL_CHUNK_COUNT][];
-
-    // utility
-
-    private QName fAttributeQName = new QName();
-
-    /**
-     * Constructor
-     *
-     * @param stringPool The string pool instance to use.
-     */
-    public XMLAttrList(StringPool stringPool) {
-        fStringPool = stringPool;
-    }
-
-    /**
-     * Reset this instance to an "empty" state.
-     *
-     * @param stringPool The string pool instance to use.
-     */
-    public void reset(StringPool stringPool) {
-        fStringPool = stringPool;
-        fCurrentHandle = -1;
-        fAttributeListHandle = -1;
-        fAttributeListLength = 0;
-        fAttrCount = 0;
-    }
-
-    public int addAttr(int attrName, int attValue, 
-                       int attType, boolean specified, boolean search) throws Exception
-    {
-        fAttributeQName.setValues(-1, attrName, attrName);
-        return addAttr(fAttributeQName, attValue, attType, specified, search);
-    }
-    /**
-     * Add an attribute to the current set.
-     *
-     * @param attrName The name of the attribute, an index in the string pool.
-     * @param attValue The value of the attribute, an index in the string pool.
-     * @param attType The type of the attribute, an index in the string pool.
-     * @param specified <code>true</code> if the attribute is specified directly; otherwise
-     *                  <code>false</code> is the attribute is provided through a default.
-     * @param search <code>true</code> if the list should be searched for a duplicate.
-     * @return The index of this attribute; or -1 is <code>search</code> was <code>true</code>
-     *         and <code>attrName</code> was already present.
-     */
-    public int addAttr(QName attribute, 
-                       int attValue, int attType, 
-                       boolean specified, boolean search) throws Exception {
-
-        int chunk;
-        int index;
-        if (search) {
-            chunk = fCurrentHandle >> CHUNK_SHIFT;
-            index = fCurrentHandle & CHUNK_MASK;
-            for (int attrIndex = fCurrentHandle; attrIndex < fAttrCount; attrIndex++) {
-                // REVISIT: Should this be localpart?
-                if (fStringPool.equalNames(fAttName[chunk][index], attribute.rawname)) {
-                    return -1;
-                }
-                if (++index == CHUNK_SIZE) {
-                    chunk++;
-                    index = 0;
-                }
-            }
-        } else {
-            chunk = fAttrCount >> CHUNK_SHIFT;
-            index = fAttrCount & CHUNK_MASK;
-        }
-        ensureCapacity(chunk, index);
-        fAttPrefix[chunk][index] = attribute.prefix;
-        fAttLocalpart[chunk][index] = attribute.localpart;
-        fAttName[chunk][index] = attribute.rawname;
-        fAttURI[chunk][index] = attribute.uri;
-        fAttValue[chunk][index] = attValue;
-        fAttType[chunk][index] = attType;
-        fAttFlags[chunk][index] = (byte)(specified ? ATTFLAG_SPECIFIED : 0);
-        return fAttrCount++;
-
-    } // addAttr(QName,int,int,boolean,boolean):int
-
-    /**
-     * Start a new set of attributes.
-     *
-     * @return The handle for the new set of attributes.
-     */
-    public int startAttrList() {
-        fCurrentHandle = fAttrCount;
-        return fCurrentHandle;
-    }
-
-    /**
-     * Terminate the current set of attributes.
-     */
-    public void endAttrList() {
-        int attrIndex = fAttrCount - 1;
-        int chunk = attrIndex >> CHUNK_SHIFT;
-        int index = attrIndex & CHUNK_MASK;
-        fAttFlags[chunk][index] |= ATTFLAG_LASTATTR;
-        fCurrentHandle = -1;
-    }
-
-    /**
-     * Get the prefix of the attribute.
-     */
-    public int getAttrPrefix(int attrIndex) {
-        if (attrIndex < 0 || attrIndex >= fAttrCount)
-            return -1;
-        int chunk = attrIndex >> CHUNK_SHIFT;
-        int index = attrIndex & CHUNK_MASK;
-        return fAttPrefix[chunk][index];
-    }
-
-    /**
-     * Return the localpart of the attribute.
-     */
-    public int getAttrLocalpart(int attrIndex) {
-        if (attrIndex < 0 || attrIndex >= fAttrCount)
-            return -1;
-        int chunk = attrIndex >> CHUNK_SHIFT;
-        int index = attrIndex & CHUNK_MASK;
-        return fAttLocalpart[chunk][index];
-    }
-
-    // REVISIT: Should this be renamed "getAttrRawname" to match?
-    /**
-     * Get the name of the attribute
-     *
-     * @param attrIndex The index of the attribute.
-     * @return The name of the attribute, an index in the string pool.
-     */
-    public int getAttrName(int attrIndex) {
-        if (attrIndex < 0 || attrIndex >= fAttrCount)
-            return -1;
-        int chunk = attrIndex >> CHUNK_SHIFT;
-        int index = attrIndex & CHUNK_MASK;
-        return fAttName[chunk][index];
-    }
-    
-    /** Sets the uri of the attribute. */
-    public void setAttrURI(int attrIndex, int uri) {
-        if (attrIndex < 0 || attrIndex >= fAttrCount)
-            return;
-        int chunk = attrIndex >> CHUNK_SHIFT;
-        int index = attrIndex & CHUNK_MASK;
-        fAttURI[chunk][index] = uri;
-    }
-
-    /** Return the uri of the attribute. */
-    public int getAttrURI(int attrIndex) {
-        if (attrIndex < 0 || attrIndex >= fAttrCount)
-            return -1;
-        int chunk = attrIndex >> CHUNK_SHIFT;
-        int index = attrIndex & CHUNK_MASK;
-        return fAttURI[chunk][index];
-    }
-
-    /**
-     * Get the value of the attribute
-     *
-     * @param attrIndex The index of the attribute.
-     * @return The value of the attribute, an index in the string pool.
-     */
-    public int getAttValue(int attrIndex) {
-        if (attrIndex < 0 || attrIndex >= fAttrCount)
-            return -1;
-        int chunk = attrIndex >> CHUNK_SHIFT;
-        int index = attrIndex & CHUNK_MASK;
-        return fAttValue[chunk][index];
-    }
-
-    /** Sets the type of the attribute. */
-    public void setAttType(int attrIndex, int attTypeIndex) {
-        if (attrIndex < 0 || attrIndex >= fAttrCount)
-            return;
-        int chunk = attrIndex >> CHUNK_SHIFT;
-        int index = attrIndex & CHUNK_MASK;
-        fAttType[chunk][index] = attTypeIndex;
-    }
-
-    /**
-     * Get the type of the attribute
-     *
-     * @param attrIndex The index of the attribute.
-     * @return The type of the attribute, an index in the string pool.
-     */
-    public int getAttType(int attrIndex) {
-        if (attrIndex < 0 || attrIndex >= fAttrCount)
-            return -1;
-        int chunk = attrIndex >> CHUNK_SHIFT;
-        int index = attrIndex & CHUNK_MASK;
-        return fAttType[chunk][index];
-    }
-
-    /**
-     * Was the attribute explicitly supplied or was it provided through a default?
-     *
-     * @param attrIndex The index of the attribute.
-     * @return <code>true</code> if the attribute was specified directly; otherwise
-     *         <code>false</code> is the attribute was provided through a default.
-     */
-    public boolean isSpecified(int attrIndex) {
-        if (attrIndex < 0 || attrIndex >= fAttrCount)
-            return true;
-        int chunk = attrIndex >> CHUNK_SHIFT;
-        int index = attrIndex & CHUNK_MASK;
-        return (fAttFlags[chunk][index] & ATTFLAG_SPECIFIED) != 0;
-    }
-
-    /**
-     * Make the resources of the current attribute list available for reuse.
-     *
-     * @param The attribute list handle.
-     */
-    public void releaseAttrList(int attrListHandle) {
-        if (attrListHandle == -1)
-            return;
-        int chunk = attrListHandle >> CHUNK_SHIFT;
-        int index = attrListHandle & CHUNK_MASK;
-        while (true) {
-            boolean last = (fAttFlags[chunk][index] & ATTFLAG_LASTATTR) != 0;
-            fAttPrefix[chunk][index] = -1;
-            fAttLocalpart[chunk][index] = -1;
-            fAttName[chunk][index] = -1;
-            fAttURI[chunk][index] = -1;
-            if ((fAttFlags[chunk][index] & ATTFLAG_SPECIFIED) != 0)
-                fStringPool.releaseString(fAttValue[chunk][index]);
-            fAttValue[chunk][index] = -1;
-            if (++index == CHUNK_SIZE) {
-                chunk++;
-                index = 0;
-            }
-            if (last)
-                break;
-        }
-        int lastIndex = (chunk << CHUNK_SHIFT) + index;
-        if (fAttrCount == lastIndex)
-            fAttrCount = attrListHandle;
-    }
-
-    /** 
-     * Get the first attribute in the attribute list.
-     *
-     * @param attrListHandle The attribute list handle.
-     * @return The index of the first attribute in the specified
-     *         attribute list or -1 if the handle is invalid.
-     */
-    public int getFirstAttr(int attrListHandle) {
-        if (attrListHandle < 0 || attrListHandle >= fAttrCount) {
-            return -1;
-        }
-        // the first attribute in a list is implemented as
-        // the same index of the attribute list handle
-        return attrListHandle;
-    }
-
-    /**
-     * Get the next attribute in the attribute list.
-     *
-     * @param attrIndex The attribute index.
-     * @return The index of the next attribute after <code>attrIndex</code> in
-     *         the same attribute list or -1 if there is no next index.
-     */
-    public int getNextAttr(int attrIndex) {
-        if (attrIndex < 0 || attrIndex + 1 >= fAttrCount) {
-            return -1;
-        }
-        int chunk = attrIndex >> CHUNK_SHIFT;
-        int index = attrIndex & CHUNK_MASK;
-        if ((fAttFlags[chunk][index] & ATTFLAG_LASTATTR) != 0) {
-            return -1;
-        }
-        // attribute lists are implemented in the
-        // chunks one after another with the last
-        // attribute having a "last" flag set
-        return attrIndex + 1;
-    }
-
-    /* AttributeList support */
-
-    /**
-     * Setup this instance to respond as an <code>AttributeList</code> implementation.
-     *
-     * @return This instance as an <code>AttributeList</code>.
-     */
-    public AttributeList getAttributeList(int attrListHandle) {
-        fAttributeListHandle = attrListHandle;
-        if (fAttributeListHandle == -1)
-            fAttributeListLength = 0;
-        else {
-            int chunk = fAttributeListHandle >> CHUNK_SHIFT;
-            int index = fAttributeListHandle & CHUNK_MASK;
-            fAttributeListLength = 1;
-            while ((fAttFlags[chunk][index] & ATTFLAG_LASTATTR) == 0) {
-                if (++index == CHUNK_SIZE) {
-                    chunk++;
-                    index = 0;
-                }
-                fAttributeListLength++;
-            }
-        }
-        return this;
-    }
-
-    /**
-     * Return the number of attributes in this list.
-     *
-     * <p>The SAX parser may provide attributes in any
-     * arbitrary order, regardless of the order in which they were
-     * declared or specified.  The number of attributes may be
-     * zero.</p>
-     *
-     * @return The number of attributes in the list.
-     */
-    public int getLength() {
-        return fAttributeListLength;
-    }
-
-    /**
-     * Return the prefix of an attribute in this list (by position).
-     */
-    public String getPrefix(int i) {
-        if (i < 0 || i >= fAttributeListLength) {
-            return null;
-        }
-        int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT;
-        int index = (fAttributeListHandle + i) & CHUNK_MASK;
-        return fStringPool.toString(fAttPrefix[chunk][index]);
-    }
-
-    /**
-     * Return the local part of an attribute in this list (by position).
-     */
-    public String getLocalpart(int i) {
-        if (i < 0 || i >= fAttributeListLength) {
-            return null;
-        }
-        int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT;
-        int index = (fAttributeListHandle + i) & CHUNK_MASK;
-        return fStringPool.toString(fAttLocalpart[chunk][index]);
-    }
-
-    /**
-     * Return the name of an attribute in this list (by position).
-     *
-     * <p>The names must be unique: the SAX parser shall not include the
-     * same attribute twice.  Attributes without values (those declared
-     * #IMPLIED without a value specified in the start tag) will be
-     * omitted from the list.</p>
-     *
-     * <p>If the attribute name has a namespace prefix, the prefix
-     * will still be attached.</p>
-     *
-     * @param i The index of the attribute in the list (starting at 0).
-     * @return The name of the indexed attribute, or null
-     *         if the index is out of range.
-     * @see #getLength
-     */
-    public String getName(int i) {
-        if (i < 0 || i >= fAttributeListLength)
-            return null;
-        int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT;
-        int index = (fAttributeListHandle + i) & CHUNK_MASK;
-        return fStringPool.toString(fAttName[chunk][index]);
-    }
-
-    /** Returns the URI of an attribute in this list (by position). */
-    public String getURI(int i) {
-        if (i < 0 || i >= fAttributeListLength)
-            return null;
-        int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT;
-        int index = (fAttributeListHandle + i) & CHUNK_MASK;
-        return fStringPool.toString(fAttURI[chunk][index]);
-    }
-
-    /**
-     * Return the type of an attribute in the list (by position).
-     *
-     * <p>The attribute type is one of the strings "CDATA", "ID",
-     * "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES",
-     * or "NOTATION" (always in upper case).</p>
-     *
-     * <p>If the parser has not read a declaration for the attribute,
-     * or if the parser does not report attribute types, then it must
-     * return the value "CDATA" as stated in the XML 1.0 Recommentation
-     * (clause 3.3.3, "Attribute-Value Normalization").</p>
-     *
-     * <p>For an enumerated attribute that is not a notation, the
-     * parser will report the type as "NMTOKEN".</p>
-     *
-     * @param i The index of the attribute in the list (starting at 0).
-     * @return The attribute type as a string, or
-     *         null if the index is out of range.
-     * @see #getLength
-     * @see #getType(java.lang.String)
-     */
-    public String getType(int i) {
-        if (i < 0 || i >= fAttributeListLength)
-            return null;
-        int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT;
-        int index = (fAttributeListHandle + i) & CHUNK_MASK;
-        int attType = fAttType[chunk][index];
-        if (attType == fStringPool.addSymbol("ENUMERATION"))
-            attType = fStringPool.addSymbol("NMTOKEN");
-        return fStringPool.toString(attType);
-    }
-
-    /**
-     * Return the value of an attribute in the list (by position).
-     *
-     * <p>If the attribute value is a list of tokens (IDREFS,
-     * ENTITIES, or NMTOKENS), the tokens will be concatenated
-     * into a single string separated by whitespace.</p>
-     *
-     * @param i The index of the attribute in the list (starting at 0).
-     * @return The attribute value as a string, or
-     *         null if the index is out of range.
-     * @see #getLength
-     * @see #getValue(java.lang.String)
-     */
-    public String getValue(int i) {
-        if (i < 0 || i >= fAttributeListLength)
-            return null;
-        int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT;
-        int index = (fAttributeListHandle + i) & CHUNK_MASK;
-        return fStringPool.toString(fAttValue[chunk][index]);
-    }
-
-    /**
-     * Return the type of an attribute in the list (by name).
-     *
-     * <p>The return value is the same as the return value for
-     * getType(int).</p>
-     *
-     * <p>If the attribute name has a namespace prefix in the document,
-     * the application must include the prefix here.</p>
-     *
-     * @param name The name of the attribute.
-     * @return The attribute type as a string, or null if no
-     *         such attribute exists.
-     * @see #getType(int)
-     */
-    public String getType(String name) {
-        int nameIndex = fStringPool.addSymbol(name);
-        if (nameIndex == -1)
-            return null;
-        int chunk = fAttributeListHandle >> CHUNK_SHIFT;
-        int index = fAttributeListHandle & CHUNK_MASK;
-        for (int i = 0; i < fAttributeListLength; i++) {
-            if (fStringPool.equalNames(fAttName[chunk][index], nameIndex)) {
-                int attType = fAttType[chunk][index];
-                if (attType == fStringPool.addSymbol("ENUMERATION"))
-                    attType = fStringPool.addSymbol("NMTOKEN");
-                return fStringPool.toString(attType);
-            }
-            if (++index == CHUNK_SIZE) {
-                chunk++;
-                index = 0;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return the value of an attribute in the list (by name).
-     *
-     * <p>The return value is the same as the return value for
-     * getValue(int).</p>
-     *
-     * <p>If the attribute name has a namespace prefix in the document,
-     * the application must include the prefix here.</p>
-     *
-     * @param i The index of the attribute in the list.
-     * @return The attribute value as a string, or null if
-     *         no such attribute exists.
-     * @see #getValue(int)
-     */
-    public String getValue(String name) {
-        int nameIndex = fStringPool.addSymbol(name);
-        if (nameIndex == -1)
-            return null;
-        int chunk = fAttributeListHandle >> CHUNK_SHIFT;
-        int index = fAttributeListHandle & CHUNK_MASK;
-        for (int i = 0; i < fAttributeListLength; i++) {
-            if (fStringPool.equalNames(fAttName[chunk][index], nameIndex))
-                return fStringPool.toString(fAttValue[chunk][index]);
-            if (++index == CHUNK_SIZE) {
-                chunk++;
-                index = 0;
-            }
-        }
-        return null;
-    }
-
-    //
-    // Private methods
-    //
-
-    /* Expand our internal data structures as needed. */
-    private boolean ensureCapacity(int chunk, int index) {
-
-        try {
-            return fAttName[chunk][index] != 0;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            int[][] newIntArray = new int[chunk * 2][];
-            System.arraycopy(fAttPrefix, 0, newIntArray, 0, chunk);
-            fAttPrefix = newIntArray;
-            newIntArray = new int[chunk * 2][];
-            System.arraycopy(fAttLocalpart, 0, newIntArray, 0, chunk);
-            fAttLocalpart = newIntArray;
-            newIntArray = new int[chunk * 2][];
-            System.arraycopy(fAttName, 0, newIntArray, 0, chunk);
-            fAttName = newIntArray;
-            newIntArray = new int[chunk * 2][];
-            System.arraycopy(fAttURI, 0, newIntArray, 0, chunk);
-            fAttURI = newIntArray;
-            newIntArray = new int[chunk * 2][];
-            System.arraycopy(fAttValue, 0, newIntArray, 0, chunk);
-            fAttValue = newIntArray;
-            newIntArray = new int[chunk * 2][];
-            System.arraycopy(fAttType, 0, newIntArray, 0, chunk);
-            fAttType = newIntArray;
-            byte[][] newByteArray = new byte[chunk * 2][];
-            System.arraycopy(fAttFlags, 0, newByteArray, 0, chunk);
-            fAttFlags = newByteArray;
-        } catch (NullPointerException ex) {
-        }
-        fAttPrefix[chunk] = new int[CHUNK_SIZE];
-        fAttLocalpart[chunk] = new int[CHUNK_SIZE];
-        fAttName[chunk] = new int[CHUNK_SIZE];
-        fAttURI[chunk] = new int[CHUNK_SIZE];
-        fAttValue[chunk] = new int[CHUNK_SIZE];
-        fAttType[chunk] = new int[CHUNK_SIZE];
-        fAttFlags[chunk] = new byte[CHUNK_SIZE];
-        return true;
-
-    } // ensureCapacity(int,int):boolean
-
-} // class XMLAttrList
diff --git a/src/org/apache/xerces/framework/XMLContentSpec.java b/src/org/apache/xerces/framework/XMLContentSpec.java
deleted file mode 100644
index aea8c10..0000000
--- a/src/org/apache/xerces/framework/XMLContentSpec.java
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.framework;
-
-import org.apache.xerces.utils.StringPool;
-
-/**
- * ContentSpec really exists to aid the parser classes in implementing
- * access to the grammar.
- * <p>
- * This class is used by the DTD scanner and the validator classes,
- * allowing them to be used separately or together.  This "struct"
- * class is used to build content models for validation, where it
- * is more efficient to fetch all of the information for each of
- * these content model "fragments" than to fetch each field one at
- * a time.  Since configurations are allowed to have validators
- * without a DTD scanner (i.e. a schema validator) and a DTD scanner
- * without a validator (non-validating processor), this class can be
- * used by each without requiring the presence of the other.
- * <p>
- * When processing element declarations, the DTD scanner will build
- * up a representation of the content model using the node types that
- * are defined here.  Since a non-validating processor only needs to
- * remember the type of content model declared (i.e. ANY, EMPTY, MIXED,
- * or CHILDREN), it is free to discard the specific details of the
- * MIXED and CHILDREN content models described using this class.
- * <p>
- * In the typical case of a validating processor reading the grammar
- * of the document from a DTD, the information about the content model
- * declared will be preserved and later "compiled" into an efficient
- * form for use during element validation.  Each content spec node
- * that is saved is assigned a unique index that is used as a handle
- * for the "value" or "otherValue" fields of other content spec nodes.
- * A leaf node has a "value" that is either an index in the string
- * pool of the element type of that leaf, or a value of -1 to indicate
- * the special "#PCDATA" leaf type used in a mixed content model.
- * <p>
- * For a mixed content model, the content spec will be made up of
- * leaf and choice content spec nodes, with an optional "zero or more"
- * node.  For example, the mixed content declaration "(#PCDATA)" would
- * contain a single leaf node with a node value of -1.  A mixed content
- * declaration of "(#PCDATA|foo)*" would have a content spec consisting
- * of two leaf nodes, for the "#PCDATA" and "foo" choices, a choice node
- * with the "value" set to the index of the "#PCDATA" leaf node and the
- * "otherValue" set to the index of the "foo" leaf node, and a "zero or
- * more" node with the "value" set to the index of the choice node.  If
- * the content model has more choices, for example "(#PCDATA|a|b)*", then
- * there will be more corresponding choice and leaf nodes, the choice
- * nodes will be chained together through the "value" field with each
- * leaf node referenced by the "otherValue" field.
- * <p>
- * For element content models, there are sequence nodes and also "zero or
- * one" and "one or more" nodes.  The leaf nodes would always have a valid
- * string pool index, as the "#PCDATA" leaf is not used in the declarations
- * for element content models.
- *
- * @version $Id$
- */
-public class XMLContentSpec {
-
-    //
-    // Constants
-    //
-
-    /** 
-     * Name or #PCDATA. Leaf nodes that represent parsed character
-     * data (#PCDATA) have values of -1.
-     */
-    public static final int CONTENTSPECNODE_LEAF = 0;
-
-    /** Represents a zero or one occurence count, '?'. */
-    public static final int CONTENTSPECNODE_ZERO_OR_ONE = 1;
-
-    /** Represents a zero or more occurence count, '*'. */
-    public static final int CONTENTSPECNODE_ZERO_OR_MORE = 2;
-    
-    /** Represents a one or more occurence count, '+'. */
-    public static final int CONTENTSPECNODE_ONE_OR_MORE = 3;
-    
-    /** Represents choice, '|'. */
-    public static final int CONTENTSPECNODE_CHOICE = 4;
-    
-    /** Represents sequence, ','. */
-    public static final int CONTENTSPECNODE_SEQ = 5;
-
-    /** 
-     * Represents any namespace specified namespace. When the element
-     * found in the document must belong to a specific namespace, 
-     * <code>otherValue</code> will contain the name of the namespace.
-     * If <code>otherValue</code> is <code>-1</code> then the element
-     * can be from any namespace.
-     * <p>
-     * Lists of valid namespaces are created from choice content spec
-     * nodes that have any content spec nodes as children.
-     */
-    public static final int CONTENTSPECNODE_ANY = 6;
-
-    /** 
-     * Represents any other namespace (XML Schema: ##other). 
-     * <p>
-     * When the content spec node type is set to CONTENTSPECNODE_ANY_OTHER, 
-     * <code>value</code> will contain the namespace that <em>cannot</em>
-     * occur.
-     */
-    public static final int CONTENTSPECNODE_ANY_OTHER = 7;
-
-    /** Represents any local element (XML Schema: ##local). */
-    public static final int CONTENTSPECNODE_ANY_LOCAL = 8;
-
-    /** prcessContent is 'lax' **/
-    public static final int CONTENTSPECNODE_ANY_LAX = 22;
-
-    public static final int CONTENTSPECNODE_ANY_OTHER_LAX = 23;
-
-    public static final int CONTENTSPECNODE_ANY_LOCAL_LAX = 24;
-
-    /** processContent is 'skip' **/
-    
-    public static final int CONTENTSPECNODE_ANY_SKIP = 38;
-
-    public static final int CONTENTSPECNODE_ANY_OTHER_SKIP = 39;
-
-    public static final int CONTENTSPECNODE_ANY_LOCAL_SKIP = 40;
-    //
-    // Data
-    //
-
-    /** 
-     * The content spec node type. 
-     *
-     * @see CONTENTSPECNODE_LEAF
-     * @see CONTENTSPECNODE_ZERO_OR_ONE
-     * @see CONTENTSPECNODE_ZERO_OR_MORE
-     * @see CONTENTSPECNODE_ONE_OR_MORE
-     * @see CONTENTSPECNODE_CHOICE
-     * @see CONTENTSPECNODE_SEQ
-     */
-    public int type;
-
-    /**
-     * The "left hand" value of the content spec node.
-     * // leaf index, single child for unary ops, left child for binary ops.
-     */
-    public int value;
-
-    /**
-     * The "right hand" value of the content spec node.
-     * // right child for binary ops
-     */
-    public int otherValue;
-
-    //
-    // Constructors
-    //
-
-    /** Default constructor. */
-    public XMLContentSpec() {
-        clear();
-    }
-
-    /** Constructs a content spec with the specified values. */
-    public XMLContentSpec(int type, int value, int otherValue) {
-        setValues(type, value, otherValue);
-    }
-
-    /** 
-     * Constructs a content spec from the values in the specified content spec.
-     */
-    public XMLContentSpec(XMLContentSpec contentSpec) {
-        setValues(contentSpec);
-    }
-
-    /**
-     * Constructs a content spec from the values specified by the given
-     * content spec provider and identifier.
-     */
-    public XMLContentSpec(XMLContentSpec.Provider provider,
-                          int contentSpecIndex) {
-        setValues(provider, contentSpecIndex);
-    }
-
-    //
-    // Public methods
-    //
-
-    /** Clears the values. */
-    public void clear() {
-        type = -1;
-        value = -1;
-        otherValue = -1;
-    }
-
-    /** Sets the values. */
-    public void setValues(int type, int value, int otherValue) {
-        this.type = type;
-        this.value = value;
-        this.otherValue = otherValue;
-    }
-    
-    /** Sets the values of the specified content spec. */
-    public void setValues(XMLContentSpec contentSpec) {
-        type = contentSpec.type;
-        value = contentSpec.value;
-        otherValue = contentSpec.otherValue;
-    }
-
-    /**
-     * Sets the values from the values specified by the given content spec
-     * provider and identifier. If the specified content spec cannot be
-     * provided, the values of this content spec are cleared.
-     */
-    public void setValues(XMLContentSpec.Provider provider,
-                          int contentSpecIndex) {
-        if (!provider.getContentSpec(contentSpecIndex, this)) {
-            clear();
-        }
-    }
-
-    //
-    // Public static methods
-    //
-
-    /** 
-     * Returns a string representation of the specified content spec 
-     * identifier in the form of a DTD element content model.
-     * <p>
-     * <strong>Note:</strong> This method is not namespace aware.
-     */
-    public static String toString(XMLContentSpec.Provider provider, 
-                                  StringPool stringPool, 
-                                  int contentSpecIndex) {
-
-        // lookup content spec node
-        XMLContentSpec contentSpec = new XMLContentSpec();
-       
-        if (provider.getContentSpec(contentSpecIndex, contentSpec)) {
-
-            // build string
-            StringBuffer str = new StringBuffer();
-            int    parentContentSpecType = contentSpec.type & 0x0f;
-            int    nextContentSpec;
-            switch (parentContentSpecType) {
-                case XMLContentSpec.CONTENTSPECNODE_LEAF: {
-                    str.append('(');
-                    if (contentSpec.value == -1 && contentSpec.otherValue == -1) {
-                        str.append("#PCDATA");
-                    }
-                    else if (contentSpec.otherValue != -1) {
-                        str.append("##any:uri="+stringPool.toString(contentSpec.otherValue));
-                    }
-                    else if (contentSpec.value == -1) {
-                        str.append("##any");
-                    }
-                    else {
-                        str.append(stringPool.toString(contentSpec.value));
-                    }
-                    str.append(')');
-                    break;
-                }
-                case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
-                    provider.getContentSpec(contentSpec.value, contentSpec);
-                    nextContentSpec = contentSpec.type;
-
-                    if (nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-                        str.append('(');
-                        str.append(stringPool.toString(contentSpec.value));
-                        str.append(')');
-                    } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE  ||
-                            nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE  ||
-                            nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
-                        str.append('(' );
-                        appendContentSpec(provider, stringPool, contentSpec, str, 
-                                                                 true, parentContentSpecType );
-                        str.append(')');
-
-                    } else {
-                        appendContentSpec(provider, stringPool, contentSpec, str, 
-                                                                 true, parentContentSpecType );
-                    }
-                    str.append('?');
-                    break;
-                }
-                case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
-                    provider.getContentSpec(contentSpec.value, contentSpec);
-                    nextContentSpec = contentSpec.type;
-
-                    if ( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-                        str.append('(');
-                        if (contentSpec.value == -1 && contentSpec.otherValue == -1) {
-                            str.append("#PCDATA");
-                        }
-                        else if (contentSpec.otherValue != -1) {
-                            str.append("##any:uri="+stringPool.toString(contentSpec.otherValue));
-                        }
-                        else if (contentSpec.value == -1) {
-                            str.append("##any");
-                        }
-                        else {
-                             appendContentSpec(provider, stringPool, contentSpec, str, 
-                                                    true, parentContentSpecType );
-                        }
-                        str.append(')');
-
-                    } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE  ||
-                        nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE  ||
-                        nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
-                        str.append('(' );
-                        appendContentSpec(provider, stringPool, contentSpec, str, 
-                                                            true, parentContentSpecType );
-                        str.append(')');
-                    } else {
-                        appendContentSpec(provider, stringPool, contentSpec, str, 
-                                                                true, parentContentSpecType );
-
-                        //str.append(stringPool.toString(contentSpec.value));
-                    }
-                    str.append('*');
-                    break;
-                }
-                case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
-                    provider.getContentSpec(contentSpec.value, contentSpec);
-                    nextContentSpec = contentSpec.type;
-
-                    if ( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-                        str.append('(');
-                        if (contentSpec.value == -1 && contentSpec.otherValue == -1) {
-                            str.append("#PCDATA");
-                        }
-                        else if (contentSpec.otherValue != -1) {
-                            str.append("##any:uri="+stringPool.toString(contentSpec.otherValue));
-                        }
-                        else if (contentSpec.value == -1) {
-                            str.append("##any");
-                        }
-                        else {
-                            str.append(stringPool.toString(contentSpec.value));
-                        }
-                        str.append(')');
-                    } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE  ||
-                        nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE  ||
-                        nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
-                        str.append('(' );
-                        appendContentSpec(provider, stringPool, contentSpec, str, 
-                                                      true, parentContentSpecType );
-                        str.append(')');
-                    } else {
-                        appendContentSpec(provider, stringPool, contentSpec, str,
-                                                            true, parentContentSpecType);
-                    }
-                    str.append('+');
-                    break;
-                }
-                case XMLContentSpec.CONTENTSPECNODE_CHOICE:
-                case XMLContentSpec.CONTENTSPECNODE_SEQ: {
-                    appendContentSpec(provider, stringPool,
-                                      contentSpec, str, true, parentContentSpecType );
-                    break;
-                }
-                case XMLContentSpec.CONTENTSPECNODE_ANY: {
-                    str.append("##any");
-                    if (contentSpec.otherValue != -1) {
-                        str.append(":uri=");
-                        str.append(stringPool.toString(contentSpec.otherValue));
-                    }
-                    break;
-                }
-                case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: {
-                    str.append("##other:uri=");
-                    str.append(stringPool.toString(contentSpec.otherValue));
-                    break;
-                }
-                case XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL: {
-                    str.append("##local");
-                    break;
-                }
-                default: {
-                    str.append("???");
-                }
-
-            } // switch type
-
-            // return string
-            return str.toString();
-        }
-
-        // not found
-        return null;
-
-    } // toString(XMLContentSpec.Provider):String
-
-    //
-    // Object methods
-    //
-
-    /** Returns a hash code for this node. */
-    public int hashCode() {
-        return type << 16 | 
-               value << 8 |
-               otherValue;
-    }
-
-    /** Returns true if the two objects are equal. */
-    public boolean equals(Object object) {
-        if (object != null && object instanceof XMLContentSpec) {
-            XMLContentSpec contentSpec = (XMLContentSpec)object;
-            return type == contentSpec.type &&
-                   value == contentSpec.value &&
-                   otherValue == contentSpec.otherValue;
-        }
-        return false;
-    }
-
-    //
-    // Private static methods
-    //
-
-    /**
-     * Appends more information to the current string buffer.
-     * <p>
-     * <strong>Note:</strong> This method does <em>not</em> preserve the
-     * contents of the content spec node.
-     */
-    private static void appendContentSpec(XMLContentSpec.Provider provider,
-                                          StringPool stringPool,
-                                          XMLContentSpec contentSpec, 
-                                          StringBuffer str, 
-                                          boolean parens,
-                                          int     parentContentSpecType ) {
-
-        int thisContentSpec = contentSpec.type & 0x0f;
-        switch (thisContentSpec) {
-            case XMLContentSpec.CONTENTSPECNODE_LEAF: {
-                if (contentSpec.value == -1 && contentSpec.otherValue == -1) {
-                    str.append("#PCDATA");
-                }
-                else if (contentSpec.value == -1 && contentSpec.otherValue != -1) {
-                    str.append("##any:uri="+stringPool.toString(contentSpec.otherValue));
-                }
-                else if (contentSpec.value == -1) {
-                    str.append("##any");
-                }
-                else {
-                    str.append(stringPool.toString(contentSpec.value));
-                }
-                break;
-            }
-            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
-                if( parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE  ||
-                    parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
-                    parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
-                    provider.getContentSpec(contentSpec.value, contentSpec);
-                    str.append('(');
-                    appendContentSpec(provider, stringPool, 
-                                      contentSpec, str, true, thisContentSpec );
-                    str.append(')');
-
-                } 
-                else {
-                    provider.getContentSpec(contentSpec.value, contentSpec);
-                    appendContentSpec(provider, stringPool, 
-                                      contentSpec, str, true, thisContentSpec );
-                }
-                str.append('?');
-                break;
-            }
-            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
-                if( parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
-                   parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
-                   parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
-                   provider.getContentSpec(contentSpec.value, contentSpec);
-                   str.append('(');
-                   appendContentSpec(provider, stringPool,
-                                      contentSpec, str, true, thisContentSpec);
-                   str.append(')' );
-                } else{
-                    provider.getContentSpec(contentSpec.value, contentSpec);
-                    appendContentSpec(provider, stringPool,
-                                     contentSpec, str, true, thisContentSpec);
-                }
-                str.append('*');
-                break;
-            }
-            case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
-                if( parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE   ||
-                    parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE  ||
-                    parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
-
-                  str.append('(');
-                  provider.getContentSpec(contentSpec.value, contentSpec);
-                  appendContentSpec(provider, stringPool,
-                                    contentSpec, str, true, thisContentSpec);
-                  str.append(')' );
-                } else {
-                    provider.getContentSpec(contentSpec.value, contentSpec);
-                    appendContentSpec(provider, stringPool,
-                                   contentSpec, str, true, thisContentSpec);
-                }
-                str.append('+');
-                break;
-            }
-            case XMLContentSpec.CONTENTSPECNODE_CHOICE:
-            case XMLContentSpec.CONTENTSPECNODE_SEQ: {
-                if (parens) {
-                    str.append('(');
-                }
-                int type = contentSpec.type;
-                int otherValue = contentSpec.otherValue;
-                provider.getContentSpec(contentSpec.value, contentSpec);
-                appendContentSpec(provider, stringPool,
-                           contentSpec, str, contentSpec.type != type, thisContentSpec);
-                if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE) {
-                    str.append('|');
-                }
-                else {
-                    str.append(',');
-                }
-                /***
-                // REVISIT: Do we need this? -Ac
-                if (++index == CHUNK_SIZE) {
-                    chunk++;
-                    index = 0;
-                }
-                /***/
-                provider.getContentSpec(otherValue, contentSpec);
-                appendContentSpec(provider, stringPool,
-                                  contentSpec, str, true, thisContentSpec);
-                if (parens) {
-                    str.append(')');
-                }
-                break;
-            }
-            case XMLContentSpec.CONTENTSPECNODE_ANY: {
-                str.append("##any");
-                if (contentSpec.otherValue != -1) {
-                    str.append(":uri=");
-                    str.append(stringPool.toString(contentSpec.otherValue));
-                }
-                break;
-            }
-            case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: {
-                str.append("##other:uri=");
-                str.append(stringPool.toString(contentSpec.otherValue));
-                break;
-            }
-            case XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL: {
-                str.append("##local");
-                break;
-            }
-            default: {
-                str.append("???");
-                break;
-            }
-
-        } // switch type
-
-    } // appendContentSpec(XMLContentSpec.Provider,StringPool,XMLContentSpec,StringBuffer,boolean)
-
-    //
-    // Interfaces
-    //
-
-    /**
-     * Provides a means for walking the structure built out of 
-     * content spec "nodes". The user of this provider interface is
-     * responsible for knowing what the content spec node values
-     * "mean". If those values refer to content spec identifiers,
-     * then the user can call back into the provider to get the
-     * next content spec node in the structure.
-     */
-    public interface Provider {
-
-        //
-        // XMLContentSpec.Provider methods
-        //
-
-        /**
-         * Fills in the provided content spec structure with content spec
-         * information for a unique identifier.
-         *
-         * @param contentSpecIndex The content spec identifier. All content
-         *                         spec "nodes" have a unique identifier.
-         * @param contentSpec      The content spec struct to fill in with
-         *                         the information.
-         *
-         * @return Returns true if the contentSpecIndex was found.
-         */
-        public boolean getContentSpec(int contentSpecIndex, XMLContentSpec contentSpec);
-
-    } // interface Provider
-
-} // class XMLContentSpec
diff --git a/src/org/apache/xerces/framework/XMLDTDScanner.java b/src/org/apache/xerces/framework/XMLDTDScanner.java
deleted file mode 100644
index 4ed5bec..0000000
--- a/src/org/apache/xerces/framework/XMLDTDScanner.java
+++ /dev/null
@@ -1,3311 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.framework;
-
-import org.apache.xerces.readers.XMLEntityHandler;
-import org.apache.xerces.readers.DefaultEntityHandler;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.utils.XMLCharacterProperties;
-import org.apache.xerces.utils.XMLMessages;
-import org.apache.xerces.validators.common.Grammar;
-import org.apache.xerces.validators.common.GrammarResolver;
-import org.apache.xerces.validators.common.XMLAttributeDecl;
-import org.apache.xerces.validators.common.XMLElementDecl;
-import org.apache.xerces.validators.dtd.DTDGrammar;
-
-import org.xml.sax.Locator;
-import org.xml.sax.SAXParseException;
-
-import java.util.StringTokenizer;
-/**
- * Default implementation of an XML DTD scanner.
- * <p>
- * Clients who wish to scan a DTD should implement
- * XMLDTDScanner.EventHandler to provide the desired behavior
- * when various DTD components are encountered.
- * <p>
- * To process the DTD, the client application should follow the 
- * following sequence:
- * <ol>
- *  <li>call scanDocTypeDecl() to scan the DOCTYPE declaration
- *  <li>call getReadingExternalEntity() to determine if scanDocTypeDecl found an
- *      external subset
- * <li>if scanning an external subset, call scanDecls(true) to process the external subset
- * </ol>
- *
- * @see XMLDTDScanner.EventHandler
- * @version $Id$
- */
-public final class XMLDTDScanner {
-    //
-    // Constants
-    //
-    //
-    // [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
-    //
-    private static final char[] version_string = { 'v','e','r','s','i','o','n' };
-    //
-    // [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
-    //
-    private static final char[] element_string = { 'E','L','E','M','E','N','T' };
-    //
-    // [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
-    //
-    private static final char[] empty_string = { 'E','M','P','T','Y' };
-    private static final char[] any_string = { 'A','N','Y' };
-    //
-    // [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*'
-    //                | '(' S? '#PCDATA' S? ')'
-    //
-    private static final char[] pcdata_string = { '#','P','C','D','A','T','A' };
-    //
-    // [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
-    //
-    private static final char[] attlist_string = { 'A','T','T','L','I','S','T' };
-    //
-    // [55] StringType ::= 'CDATA'
-    //
-    private static final char[] cdata_string = { 'C','D','A','T','A' };
-    //
-    // [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES'
-    //                        | 'NMTOKEN' | 'NMTOKENS'
-    //
-    // Note: We search for common substrings always trying to move forward
-    //
-    //  'ID'      - Common prefix of ID, IDREF and IDREFS
-    //  'REF'     - Common substring of IDREF and IDREFS after matching ID prefix
-    //  'ENTIT'   - Common prefix of ENTITY and ENTITIES
-    //  'IES'     - Suffix of ENTITIES
-    //  'NMTOKEN' - Common prefix of NMTOKEN and NMTOKENS
-    //
-    private static final char[] id_string = { 'I','D' };
-    private static final char[] ref_string = { 'R','E','F' };
-    private static final char[] entit_string = { 'E','N','T','I','T' };
-    private static final char[] ies_string = { 'I','E','S' };
-    private static final char[] nmtoken_string = { 'N','M','T','O','K','E','N' };
-    //
-    // [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
-    // [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
-    //
-    private static final char[] notation_string = { 'N','O','T','A','T','I','O','N' };
-    //
-    // [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
-    //
-    private static final char[] required_string = { '#','R','E','Q','U','I','R','E','D' };
-    private static final char[] implied_string = { '#','I','M','P','L','I','E','D' };
-    private static final char[] fixed_string = { '#','F','I','X','E','D' };
-    //
-    // [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
-    //
-    private static final char[] include_string = { 'I','N','C','L','U','D','E' };
-    //
-    // [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
-    //
-    private static final char[] ignore_string = { 'I','G','N','O','R','E' };
-    //
-    // [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
-    // [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
-    //
-    private static final char[] entity_string = { 'E','N','T','I','T','Y' };
-    //
-    // [75] ExternalID ::= 'SYSTEM' S SystemLiteral
-    //                     | 'PUBLIC' S PubidLiteral S SystemLiteral
-    // [83] PublicID ::= 'PUBLIC' S PubidLiteral
-    //
-    private static final char[] system_string = { 'S','Y','S','T','E','M' };
-    private static final char[] public_string = { 'P','U','B','L','I','C' };
-    //
-    // [76] NDataDecl ::= S 'NDATA' S Name
-    //
-    private static final char[] ndata_string = { 'N','D','A','T','A' };
-    //
-    // [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'" )
-    //
-    private static final char[] encoding_string = { 'e','n','c','o','d','i','n','g' };
-    //
-    // Instance Variables
-    //
-    private DTDGrammar fDTDGrammar = null;
-    private GrammarResolver fGrammarResolver = null;
-    private boolean fNamespacesEnabled = false;
-    private boolean fValidationEnabled = false;
-    private XMLElementDecl fTempElementDecl = new XMLElementDecl();
-    private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
-    private QName fElementQName = new QName();
-    private QName fAttributeQName = new QName();
-    private QName fElementRefQName = new QName();
-    private EventHandler fEventHandler = null;
-    private XMLDocumentHandler.DTDHandler fDTDHandler = null;
-    private StringPool fStringPool = null;
-    private XMLErrorReporter fErrorReporter = null;
-    private XMLEntityHandler fEntityHandler = null;
-    private XMLEntityHandler.EntityReader fEntityReader = null;
-    private XMLEntityHandler.CharBuffer fLiteralData = null;
-    private int fReaderId = -1;
-    private int fSystemLiteral = -1;
-    private int fPubidLiteral = -1;
-    private int[] fOpStack = null;
-    private int[] fNodeIndexStack = null;
-    private int[] fPrevNodeIndexStack = null;
-    private int fScannerState = SCANNER_STATE_INVALID;
-    private int fIncludeSectDepth = 0;
-    private int fDoctypeReader = -1;
-    private int fExternalSubsetReader = -1;
-    private int fDefaultAttValueReader = -1;
-    private int fDefaultAttValueElementType = -1;
-    private int fDefaultAttValueAttrName = -1;
-    private int fDefaultAttValueOffset = -1;
-    private int fDefaultAttValueMark = -1;
-    private int fEntityValueReader = -1;
-    private int fEntityValueMark = -1;
-    private int fXMLSymbol = -1;
-    private int fXMLNamespace = -1;
-    private int fXMLSpace = -1;
-    private int fDefault = -1;
-    private int fPreserve = -1;
-    private int fScannerMarkupDepth = 0;
-    private int fScannerParenDepth = 0;
-    //
-    // Constructors
-    //
-    public XMLDTDScanner(StringPool stringPool,
-                         XMLErrorReporter errorReporter,
-                         XMLEntityHandler entityHandler,
-                         XMLEntityHandler.CharBuffer literalData) {
-        fStringPool = stringPool;
-        fErrorReporter = errorReporter;
-        fEntityHandler = entityHandler;
-        fLiteralData = literalData;
-        init();
-    }
-
-    /**
-     * Set the event handler
-     *
-     * @param eventHandler The place to send our callbacks.
-     */
-    public void setEventHandler(XMLDTDScanner.EventHandler eventHandler) {
-        fEventHandler = eventHandler;
-    }
-
-    /** Set the DTD handler. */
-    public void setDTDHandler(XMLDocumentHandler.DTDHandler dtdHandler) {
-        fDTDHandler = dtdHandler;
-    }
-
-    /** Sets the grammar resolver. */
-    public void setGrammarResolver(GrammarResolver resolver) {
-        fGrammarResolver = resolver;
-    }
-
-    /** set fNamespacesEnabled  **/
-    public void setNamespacesEnabled(boolean enabled) {
-        fNamespacesEnabled = enabled;
-    }
-    
-    /** set fValidationEnabled  **/
-    public void setValidationEnabled(boolean enabled) {
-        fValidationEnabled = enabled;
-    }
-
-    /**
-     * Is the XMLDTDScanner reading from an external entity?
-     *
-     * This will be true, in particular if there was an external subset
-     *
-     * @return true if the XMLDTDScanner is reading from an external entity.
-     */
-    public boolean getReadingExternalEntity() {
-        return fReaderId != fDoctypeReader;
-    }
-    /**
-     * Is the scanner reading a ContentSpec?
-     * 
-     * @return true if the scanner is reading a ContentSpec
-     */
-    public boolean getReadingContentSpec() {
-        return getScannerState() == SCANNER_STATE_CONTENTSPEC;
-    }
-    /**
-     * Report the markup nesting depth.  This allows a client to
-     * perform validation checks for correct markup nesting.  This keeps
-     * scanning and validation separate.
-     *
-     * @return the markup nesting depth
-     */
-    public int markupDepth() {
-        return fScannerMarkupDepth;
-    }
-    private int increaseMarkupDepth() {
-        return fScannerMarkupDepth++;
-    }
-    private int decreaseMarkupDepth() {
-        return fScannerMarkupDepth--;
-    }
-    /**
-     * Report the parenthesis nesting depth.  This allows a client to
-     * perform validation checks for correct parenthesis balancing.  This keeps 
-     * scanning and validation separate.
-     *
-     * @return the parenthesis depth
-     */
-    public int parenDepth() {
-        return fScannerParenDepth;
-    }
-    private void setParenDepth(int parenDepth) {
-        fScannerParenDepth = parenDepth;
-    }
-    private void increaseParenDepth() {
-        fScannerParenDepth++;
-    }
-    private void decreaseParenDepth() {
-        fScannerParenDepth--;
-    }
-    //
-    //
-    //
-    /**
-     * Allow XMLDTDScanner to be reused.  This method is called from an
-     * XMLParser reset method, which passes the StringPool to be used
-     * by the reset DTD scanner instance.
-     *
-     * @param stringPool the string pool to be used by XMLDTDScanner.  
-     */
-    public void reset(StringPool stringPool, XMLEntityHandler.CharBuffer literalData) throws Exception {
-        fStringPool = stringPool;
-        fLiteralData = literalData;
-        fEntityReader = null;
-        fReaderId = -1;
-        fSystemLiteral = -1;
-        fPubidLiteral = -1;
-        fOpStack = null;
-        fNodeIndexStack = null;
-        fPrevNodeIndexStack = null;
-        fScannerState = SCANNER_STATE_INVALID;
-        fIncludeSectDepth = 0;
-        fDoctypeReader = -1;
-        fExternalSubsetReader = -1;
-        fDefaultAttValueReader = -1;
-        fDefaultAttValueElementType = -1;
-        fDefaultAttValueAttrName = -1;
-        fDefaultAttValueOffset = -1;
-        fDefaultAttValueMark = -1;
-        fEntityValueReader = -1;
-        fEntityValueMark = -1;
-        fScannerMarkupDepth = 0;
-        fScannerParenDepth = 0;
-        init();
-    }
-    private void init() {
-        fXMLSymbol = fStringPool.addSymbol("xml");
-        fXMLNamespace = fStringPool.addSymbol("http://www.w3.org/XML/1998/namespace");
-
-        fXMLSpace = fStringPool.addSymbol("xml:space");
-        fDefault = fStringPool.addSymbol("default");
-        fPreserve = fStringPool.addSymbol("preserve");
-    }
-
-    //
-    // Interfaces
-    //
-
-    /**
-     * This interface must be implemented by the users of the XMLDTDScanner class.
-     * These methods form the abstraction between the implementation semantics and the
-     * more generic task of scanning the DTD-specific XML grammar.
-     */
-    public interface EventHandler {
-
-        /** Start of DTD. */
-        public void callStartDTD() throws Exception;
-
-        /** End of DTD. */
-        public void callEndDTD() throws Exception;
-
-        /**
-         * Signal the Text declaration of an external entity.
-         *
-         * @param version the handle in the string pool for the version number
-         * @param encoding the handle in the string pool for the encoding
-         * @exception java.lang.Exception
-         */
-        public void callTextDecl(int version, int encoding) throws Exception;
-        /**
-         * Called when the doctype decl is scanned
-         *
-         * @param rootElementType handle of the rootElement
-         * @param publicId StringPool handle of the public id
-         * @param systemId StringPool handle of the system id
-         * @exception java.lang.Exception
-         */
-        public void doctypeDecl(QName rootElement, int publicId, int systemId) throws Exception;
-        /**
-         * Called when the DTDScanner starts reading from the external subset
-         *
-         * @param publicId StringPool handle of the public id
-         * @param systemId StringPool handle of the system id
-         * @exception java.lang.Exception
-         */
-        public void startReadingFromExternalSubset(int publicId, int systemId) throws Exception;
-        /**
-         * Called when the DTDScanner stop reading from the external subset
-         *
-         * @exception java.lang.Exception
-         */
-        public void stopReadingFromExternalSubset() throws Exception;
-        /**
-         * Add an element declaration (forward reference)
-         *
-         * @param handle to the name of the element being declared
-         * @return handle to the element whose declaration was added
-         * @exception java.lang.Exception
-         */
-        public int addElementDecl(QName elementDecl) throws Exception;
-        /**
-         * Add an element declaration
-         *
-         * @param handle to the name of the element being declared
-         * @param contentSpecType handle to the type name of the content spec
-         * @param ContentSpec handle to the content spec node for the contentSpecType
-         * @return handle to the element declaration that was added 
-         * @exception java.lang.Exception
-         */
-        public int addElementDecl(QName elementDecl, int contentSpecType, int contentSpec, boolean isExternal) throws Exception;
-        /**
-         * Add an attribute definition
-         *
-         * @param handle to the element whose attribute is being declared
-         * @param attName StringPool handle to the attribute name being declared
-         * @param attType type of the attribute
-         * @param enumeration StringPool handle of the attribute's enumeration list (if any)
-         * @param attDefaultType an integer value denoting the DefaultDecl value
-         * @param attDefaultValue StringPool handle of this attribute's default value
-         * @return handle to the attribute definition
-         * @exception java.lang.Exception
-         */
-        public int addAttDef(QName elementDecl, QName attributeDecl, 
-                             int attType, boolean attList, int enumeration, 
-                             int attDefaultType, int attDefaultValue, boolean isExternal) throws Exception;
-        /**
-         * create an XMLContentSpec for a leaf
-         *
-         * @param nameIndex StringPool handle to the name (Element) for the node
-         * @return handle to the newly create XMLContentSpec
-         * @exception java.lang.Exception
-         */
-        public int addUniqueLeafNode(int nameIndex) throws Exception;
-        /**
-         * Create an XMLContentSpec for a single non-leaf
-         * 
-         * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
-         * @param nodeValue handle to an XMLContentSpec
-         * @return handle to the newly create XMLContentSpec
-         * @exception java.lang.Exception
-         */
-        public int addContentSpecNode(int nodeType, int nodeValue) throws Exception;
-        /**
-         * Create an XMLContentSpec for a two child leaf
-         *
-         * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
-         * @param leftNodeIndex handle to an XMLContentSpec
-         * @param rightNodeIndex handle to an XMLContentSpec
-         * @return handle to the newly create XMLContentSpec
-         * @exception java.lang.Exception
-         */
-        public int addContentSpecNode(int nodeType, int leftNodeIndex, int rightNodeIndex) throws Exception;
-        /**
-         * Create a string representation of an XMLContentSpec tree
-         * 
-         * @param handle to an XMLContentSpec
-         * @return String representation of the content spec tree
-         * @exception java.lang.Exception
-         */
-        public String getContentSpecNodeAsString(int nodeIndex) throws Exception;
-        /**
-         * Start the scope of an entity declaration.
-         *
-         * @return <code>true</code> on success; otherwise
-         *         <code>false</code> if the entity declaration is recursive.
-         * @exception java.lang.Exception
-         */
-        public boolean startEntityDecl(boolean isPE, int entityName) throws Exception;
-        /**
-         * End the scope of an entity declaration.
-         * @exception java.lang.Exception
-         */
-        public void endEntityDecl() throws Exception;
-        /**
-         * Add a declaration for an internal parameter entity
-         *
-         * @param name StringPool handle of the parameter entity name
-         * @param value StringPool handle of the parameter entity value
-         * @return handle to the parameter entity declaration
-         * @exception java.lang.Exception
-         */
-        public int addInternalPEDecl(int name, int value) throws Exception;
-        /**
-         * Add a declaration for an external parameter entity
-         *
-         * @param name StringPool handle of the parameter entity name
-         * @param publicId StringPool handle of the publicId
-         * @param systemId StringPool handle of the systemId
-         * @return handle to the parameter entity declaration
-         * @exception java.lang.Exception
-         */
-        public int addExternalPEDecl(int name, int publicId, int systemId) throws Exception;
-        /**
-         * Add a declaration for an internal entity
-         *
-         * @param name StringPool handle of the entity name
-         * @param value StringPool handle of the entity value
-         * @return handle to the entity declaration
-         * @exception java.lang.Exception
-         */
-        public int addInternalEntityDecl(int name, int value) throws Exception;
-        /**
-         * Add a declaration for an entity
-         *
-         * @param name StringPool handle of the entity name
-         * @param publicId StringPool handle of the publicId
-         * @param systemId StringPool handle of the systemId
-         * @return handle to the entity declaration
-         * @exception java.lang.Exception
-         */
-        public int addExternalEntityDecl(int name, int publicId, int systemId) throws Exception;
-        /**
-         * Add a declaration for an unparsed entity
-         *
-         * @param name StringPool handle of the entity name
-         * @param publicId StringPool handle of the publicId
-         * @param systemId StringPool handle of the systemId
-         * @param notationName StringPool handle of the notationName
-         * @return handle to the entity declaration
-         * @exception java.lang.Exception
-         */
-        public int addUnparsedEntityDecl(int name, int publicId, int systemId, int notationName) throws Exception;
-        /**
-         * Called when the scanner start scanning an enumeration
-         * @return StringPool handle to a string list that will hold the enumeration names
-         * @exception java.lang.Exception
-         */
-        public int startEnumeration() throws Exception;
-        /**
-         * Add a name to an enumeration
-         * @param enumIndex StringPool handle to the string list for the enumeration
-         * @param elementType handle to the element that owns the attribute with the enumeration
-         * @param attrName StringPool handle to the name of the attribut with the enumeration
-         * @param nameIndex StringPool handle to the name to be added to the enumeration
-         * @param isNotationType true if the enumeration is an enumeration of NOTATION names
-         * @exception java.lang.Exception
-         */
-        public void addNameToEnumeration(int enumIndex, int elementType, int attrName, int nameIndex, boolean isNotationType) throws Exception;
-        /**
-         * Finish processing an enumeration
-         *
-         * @param enumIndex handle to the string list which holds the enumeration to be finshed.
-         * @exception java.lang.Exception
-         */
-        public void endEnumeration(int enumIndex) throws Exception;
-        /**
-         * Add a declaration for a notation
-         *
-         * @param notationName
-         * @param publicId
-         * @param systemId
-         * @return handle to the notation declaration
-         * @exception java.lang.Exception
-         */
-        public int addNotationDecl(int notationName, int publicId, int systemId) throws Exception;
-        /**
-         * Called when a comment has been scanned
-         *
-         * @param data StringPool handle of the comment text
-         * @exception java.lang.Exception
-         */
-        public void callComment(int data) throws Exception;
-        /**
-         * Called when a processing instruction has been scanned
-         * @param piTarget StringPool handle of the PI target
-         * @param piData StringPool handle of the PI data
-         * @exception java.lang.Exception
-         */
-        public void callProcessingInstruction(int piTarget, int piData) throws Exception;
-        /**
-         * Supports DOM Level 2 internalSubset additions.
-         * Called when the internal subset is completely scanned.
-         */
-        public void internalSubset(int internalSubset) throws Exception;
-    }
-    //
-    //
-    //
-    
-    /** Report a recoverable xml error. */
-    protected void reportRecoverableXMLError(int majorCode, int minorCode, 
-                                             int stringIndex1) 
-        throws Exception {
-
-        Object[] args = { fStringPool.toString(stringIndex1) };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-
-    } // reportRecoverableXMLError(int,int,int)
-
-    /** Report a recoverable xml error. */
-    protected void reportRecoverableXMLError(int majorCode, int minorCode, 
-                                         String string1) throws Exception {
-
-        Object[] args = { string1 };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-
-    } // reportRecoverableXMLError(int,int,String)
-    
-    /** Report a recoverable xml error. */
-    protected void reportRecoverableXMLError(int majorCode, int minorCode, 
-                                             String string1, String string2) 
-        throws Exception {
-
-        Object[] args = { string1, string2 };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-
-    } // reportRecoverableXMLError(int,int,String,String)
-    
- 
-    private void reportFatalXMLError(int majorCode, int minorCode) throws Exception {
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   null,
-                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-    }
-    private void reportFatalXMLError(int majorCode, int minorCode, int stringIndex1) throws Exception {
-        Object[] args = { fStringPool.toString(stringIndex1) };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-    }
-    private void reportFatalXMLError(int majorCode, int minorCode, String string1) throws Exception {
-        Object[] args = { string1 };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-    }
-    private void reportFatalXMLError(int majorCode, int minorCode, int stringIndex1, int stringIndex2) throws Exception {
-        Object[] args = { fStringPool.toString(stringIndex1),
-                          fStringPool.toString(stringIndex2) };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-    }
-    private void reportFatalXMLError(int majorCode, int minorCode, String string1, String string2) throws Exception {
-        Object[] args = { string1, string2 };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-    }
-    private void reportFatalXMLError(int majorCode, int minorCode, String string1, String string2, String string3) throws Exception {
-        Object[] args = { string1, string2, string3 };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-    }
-    private void abortMarkup(int majorCode, int minorCode) throws Exception {
-        reportFatalXMLError(majorCode, minorCode);
-        skipPastEndOfCurrentMarkup();
-    }
-    private void abortMarkup(int majorCode, int minorCode, int stringIndex1) throws Exception {
-        reportFatalXMLError(majorCode, minorCode, stringIndex1);
-        skipPastEndOfCurrentMarkup();
-    }
-    private void abortMarkup(int majorCode, int minorCode, String string1) throws Exception {
-        reportFatalXMLError(majorCode, minorCode, string1);
-        skipPastEndOfCurrentMarkup();
-    }
-    private void abortMarkup(int majorCode, int minorCode, int stringIndex1, int stringIndex2) throws Exception {
-        reportFatalXMLError(majorCode, minorCode, stringIndex1, stringIndex2);
-        skipPastEndOfCurrentMarkup();
-    }
-    private void skipPastEndOfCurrentMarkup() throws Exception {
-        fEntityReader.skipToChar('>');
-        if (fEntityReader.lookingAtChar('>', true))
-            decreaseMarkupDepth();
-    }
-    //
-    //
-    //
-    static private final int SCANNER_STATE_INVALID = -1;
-    static private final int SCANNER_STATE_END_OF_INPUT = 0;
-    static private final int SCANNER_STATE_DOCTYPEDECL = 50;
-    static private final int SCANNER_STATE_MARKUP_DECL = 51;
-    static private final int SCANNER_STATE_TEXTDECL = 53;
-    static private final int SCANNER_STATE_COMMENT = 54;
-    static private final int SCANNER_STATE_PI = 55;
-    static private final int SCANNER_STATE_DEFAULT_ATTRIBUTE_VALUE = 56;
-    static private final int SCANNER_STATE_CONTENTSPEC = 57;
-    static private final int SCANNER_STATE_ENTITY_VALUE = 58;
-    static private final int SCANNER_STATE_SYSTEMLITERAL = 59;
-    static private final int SCANNER_STATE_PUBIDLITERAL = 60;
-
-    private int setScannerState(int scannerState) {
-        int prevState = fScannerState;
-        fScannerState = scannerState;
-        return prevState;
-    }
-    private int getScannerState() {
-        return fScannerState;
-    }
-    private void restoreScannerState(int scannerState) {
-        if (fScannerState != SCANNER_STATE_END_OF_INPUT)
-            fScannerState = scannerState;
-    }
-    /**
-     * Change readers
-     *
-     * @param nextReader the new reader that the scanner will use
-     * @param nextReaderId id of the reader to change to
-     * @exception throws java.lang.Exception
-     */
-    public void readerChange(XMLEntityHandler.EntityReader nextReader, int nextReaderId) throws Exception {
-        fEntityReader = nextReader;
-        fReaderId = nextReaderId;
-        if (fScannerState == SCANNER_STATE_DEFAULT_ATTRIBUTE_VALUE) {
-            fDefaultAttValueOffset = fEntityReader.currentOffset();
-            fDefaultAttValueMark = fDefaultAttValueOffset;
-        } else if (fScannerState == SCANNER_STATE_ENTITY_VALUE) {
-            fEntityValueMark = fEntityReader.currentOffset();
-        }
-    }
-    /**
-     * Handle the end of input
-     *
-     * @param entityName the handle in the string pool of the name of the entity which has reached end of input
-     * @param moreToFollow if true, there is still input left to process in other readers
-     * @exception java.lang.Exception
-     */
-    public void endOfInput(int entityNameIndex, boolean moreToFollow) throws Exception {
-        if (fValidationEnabled ) {
-            int readerDepth = fEntityHandler.getReaderDepth();
-            if (getReadingContentSpec()) {
-                int parenDepth = parenDepth();
-                if (readerDepth != parenDepth) {
-                    reportRecoverableXMLError(XMLMessages.MSG_IMPROPER_GROUP_NESTING,
-                                                XMLMessages.VC_PROPER_GROUP_PE_NESTING,
-                                                entityNameIndex);
-                }
-            } else {
-                int markupDepth = markupDepth();
-                if (readerDepth != markupDepth) {
-                    reportRecoverableXMLError(XMLMessages.MSG_IMPROPER_DECLARATION_NESTING,
-                                                XMLMessages.VC_PROPER_DECLARATION_PE_NESTING,
-                                                entityNameIndex);
-                }
-            }
-        }
-        //REVISIT, why are we doing this?
-        moreToFollow = fReaderId != fExternalSubsetReader;
-
-//      System.out.println("current Scanner state " + getScannerState() +","+ fScannerState + moreToFollow);
-        switch (fScannerState) {
-        case SCANNER_STATE_INVALID:
-            throw new RuntimeException("FWK004 XMLDTDScanner.endOfInput: cannot happen: 2"+"\n2");
-        case SCANNER_STATE_END_OF_INPUT:
-            break;
-        case SCANNER_STATE_MARKUP_DECL:
-            if (!moreToFollow && fIncludeSectDepth > 0) {
-                reportFatalXMLError(XMLMessages.MSG_INCLUDESECT_UNTERMINATED,
-                                    XMLMessages.P62_UNTERMINATED);
-            }
-            break;
-        case SCANNER_STATE_DOCTYPEDECL:
-            throw new RuntimeException("FWK004 XMLDTDScanner.endOfInput: cannot happen: 2.5"+"\n2.5");
-//            break;
-        case SCANNER_STATE_TEXTDECL:
-// REVISIT            reportFatalXMLError(XMLMessages.MSG_ATTVAL0);
-            break;
-        case SCANNER_STATE_SYSTEMLITERAL:
-            if (!moreToFollow) {
-                reportFatalXMLError(XMLMessages.MSG_SYSTEMID_UNTERMINATED,
-                                    XMLMessages.P11_UNTERMINATED);
-            } else {
-// REVISIT                reportFatalXMLError(XMLMessages.MSG_ATTVAL0);
-            }
-            break;
-        case SCANNER_STATE_PUBIDLITERAL:
-            if (!moreToFollow) {
-                reportFatalXMLError(XMLMessages.MSG_PUBLICID_UNTERMINATED,
-                                    XMLMessages.P12_UNTERMINATED);
-            } else {
-// REVISIT                reportFatalXMLError(XMLMessages.MSG_ATTVAL0);
-            }
-            break;
-        case SCANNER_STATE_COMMENT:
-            if (!moreToFollow && !getReadingExternalEntity()) {
-                reportFatalXMLError(XMLMessages.MSG_COMMENT_UNTERMINATED,
-                                    XMLMessages.P15_UNTERMINATED);
-            } else {
-                //
-                // REVISIT - HACK !!!  code changed to pass incorrect OASIS test 'invalid--001'
-                //  Uncomment the next line to conform to the spec...
-                //
-                //reportFatalXMLError(XMLMessages.MSG_COMMENT_NOT_IN_ONE_ENTITY,
-                //                    XMLMessages.P78_NOT_WELLFORMED);
-            }
-            break;
-        case SCANNER_STATE_PI:
-            if (!moreToFollow) {
-                reportFatalXMLError(XMLMessages.MSG_PI_UNTERMINATED,
-                                    XMLMessages.P16_UNTERMINATED);
-            } else {
-                reportFatalXMLError(XMLMessages.MSG_PI_NOT_IN_ONE_ENTITY,
-                                    XMLMessages.P78_NOT_WELLFORMED);
-            }
-            break;
-        case SCANNER_STATE_DEFAULT_ATTRIBUTE_VALUE:
-            if (!moreToFollow) {
-                reportFatalXMLError(XMLMessages.MSG_ATTRIBUTE_VALUE_UNTERMINATED,
-                                    XMLMessages.P10_UNTERMINATED,
-                                    fDefaultAttValueElementType,
-                                    fDefaultAttValueAttrName);
-            } else if (fReaderId == fDefaultAttValueReader) {
-// REVISIT                reportFatalXMLError(XMLMessages.MSG_ATTVAL0);
-            } else {
-                fEntityReader.append(fLiteralData, fDefaultAttValueMark, fDefaultAttValueOffset - fDefaultAttValueMark);
-            }
-            break;
-        case SCANNER_STATE_CONTENTSPEC:
-            break;
-        case SCANNER_STATE_ENTITY_VALUE:
-            if (fReaderId == fEntityValueReader) {
-// REVISIT                reportFatalXMLError(XMLMessages.MSG_ATTVAL0);
-            } else {
-                fEntityReader.append(fLiteralData, fEntityValueMark, fEntityReader.currentOffset() - fEntityValueMark);
-            }
-            break;
-        default:
-            throw new RuntimeException("FWK004 XMLDTDScanner.endOfInput: cannot happen: 3"+"\n3");
-        }
-        if (!moreToFollow) {
-            setScannerState(SCANNER_STATE_END_OF_INPUT);
-        }
-    }
-    //
-    // [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
-    //
-    private int scanCharRef() throws Exception {
-        int valueOffset = fEntityReader.currentOffset();
-        boolean hex = fEntityReader.lookingAtChar('x', true);
-        int num = fEntityReader.scanCharRef(hex);
-        if (num < 0) {
-            switch (num) {
-            case XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED:
-                reportFatalXMLError(XMLMessages.MSG_SEMICOLON_REQUIRED_IN_CHARREF,
-                                    XMLMessages.P66_SEMICOLON_REQUIRED);
-                return -1;
-            case XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR:
-                int majorCode = hex ? XMLMessages.MSG_HEXDIGIT_REQUIRED_IN_CHARREF :
-                                      XMLMessages.MSG_DIGIT_REQUIRED_IN_CHARREF;
-                int minorCode = hex ? XMLMessages.P66_HEXDIGIT_REQUIRED :
-                                      XMLMessages.P66_DIGIT_REQUIRED;
-                reportFatalXMLError(majorCode, minorCode);
-                return -1;
-            case XMLEntityHandler.CHARREF_RESULT_OUT_OF_RANGE:
-                num = 0x110000; // this will cause the right error to be reported below...
-                break;
-            }
-        }
-        //
-        //  [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF]        // any Unicode character, excluding the
-        //               | [#xE000-#xFFFD] | [#x10000-#x10FFFF] // surrogate blocks, FFFE, and FFFF.
-        //
-        if (num < 0x20) {
-            if (num == 0x09 || num == 0x0A || num == 0x0D) {
-                return num;
-            }
-        } else if (num <= 0xD7FF || (num >= 0xE000 && (num <= 0xFFFD || (num >= 0x10000 && num <= 0x10FFFF)))) {
-            return num;
-        }
-        int valueLength = fEntityReader.currentOffset() - valueOffset;
-        reportFatalXMLError(XMLMessages.MSG_INVALID_CHARREF,
-                            XMLMessages.WFC_LEGAL_CHARACTER,
-                            fEntityReader.addString(valueOffset, valueLength));
-        return -1;
-    }
-    //
-    // From the standard:
-    //
-    // [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
-    //
-    // Called after scanning past '<!--'
-    //
-    private void scanComment() throws Exception
-    {
-        int commentOffset = fEntityReader.currentOffset();
-        boolean sawDashDash = false;
-        int previousState = setScannerState(SCANNER_STATE_COMMENT);
-        while (fScannerState == SCANNER_STATE_COMMENT) {
-            if (fEntityReader.lookingAtChar('-', false)) {
-                int nextEndOffset = fEntityReader.currentOffset();
-                int endOffset = 0;
-                fEntityReader.lookingAtChar('-', true);
-                int offset = fEntityReader.currentOffset();
-                int count = 1;
-                while (fEntityReader.lookingAtChar('-', true)) {
-                    count++;
-                    endOffset = nextEndOffset;
-                    nextEndOffset = offset;
-                    offset = fEntityReader.currentOffset();
-                }
-                if (count > 1) {
-                    if (fEntityReader.lookingAtChar('>', true)) {
-                        if (!sawDashDash && count > 2) {
-                            reportFatalXMLError(XMLMessages.MSG_DASH_DASH_IN_COMMENT,
-                                                XMLMessages.P15_DASH_DASH);
-                            sawDashDash = true;
-                        }
-                        decreaseMarkupDepth();
-                        int comment = fEntityReader.addString(commentOffset, endOffset - commentOffset);
-                        fDTDGrammar.callComment(comment);
-                        if (fDTDHandler != null) {
-                            fDTDHandler.comment(comment);
-                        }
-                        restoreScannerState(previousState);
-                        return;
-                    } else if (!sawDashDash) {
-                        reportFatalXMLError(XMLMessages.MSG_DASH_DASH_IN_COMMENT,
-                                            XMLMessages.P15_DASH_DASH);
-                        sawDashDash = true;
-                    }
-                }
-            } else {
-                if (!fEntityReader.lookingAtValidChar(true)) {
-                    int invChar = fEntityReader.scanInvalidChar();
-                    if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                        if (invChar >= 0) {
-                            reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_COMMENT,
-                                                XMLMessages.P15_INVALID_CHARACTER,
-                                                Integer.toHexString(invChar));
-                        }
-                    }
-                }
-            }
-        }
-        restoreScannerState(previousState);
-    }
-    //
-    // From the standard:
-    //
-    // [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
-    // [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
-    //
-    private void scanPI(int piTarget) throws Exception
-    {
-        String piTargetString = fStringPool.toString(piTarget);
-        if (piTargetString.length() == 3 &&
-            (piTargetString.charAt(0) == 'X' || piTargetString.charAt(0) == 'x') &&
-            (piTargetString.charAt(1) == 'M' || piTargetString.charAt(1) == 'm') &&
-            (piTargetString.charAt(2) == 'L' || piTargetString.charAt(2) == 'l')) {
-            abortMarkup(XMLMessages.MSG_RESERVED_PITARGET,
-                        XMLMessages.P17_RESERVED_PITARGET);
-            return;
-        }
-        int prevState = setScannerState(SCANNER_STATE_PI);
-        int piDataOffset = -1;
-        int piDataLength = 0;
-        if (!fEntityReader.lookingAtSpace(true)) {
-            if (!fEntityReader.lookingAtChar('?', true) || !fEntityReader.lookingAtChar('>', true)) {
-                if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                    abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_IN_PI,
-                                XMLMessages.P16_WHITESPACE_REQUIRED);
-                    restoreScannerState(prevState);
-                }
-                return;
-            }
-            decreaseMarkupDepth();
-            restoreScannerState(prevState);
-        } else {
-            fEntityReader.skipPastSpaces();
-            piDataOffset = fEntityReader.currentOffset();
-            while (fScannerState == SCANNER_STATE_PI) {
-                while (fEntityReader.lookingAtChar('?', false)) {
-                    int offset = fEntityReader.currentOffset();
-                    fEntityReader.lookingAtChar('?', true);
-                    if (fEntityReader.lookingAtChar('>', true)) {
-                        piDataLength = offset - piDataOffset;
-                        decreaseMarkupDepth();
-                        restoreScannerState(prevState);
-                        break;
-                    }
-                }
-                if (fScannerState != SCANNER_STATE_PI)
-                    break;
-                if (!fEntityReader.lookingAtValidChar(true)) {
-                    int invChar = fEntityReader.scanInvalidChar();
-                    if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                        if (invChar >= 0) {
-                            reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_PI,
-                                                XMLMessages.P16_INVALID_CHARACTER,
-                                                Integer.toHexString(invChar));
-                        }
-                        skipPastEndOfCurrentMarkup();
-                        restoreScannerState(prevState);
-                    }
-                    return;
-                }
-            }
-        }
-        int piData = piDataLength == 0 ?
-                     StringPool.EMPTY_STRING : fEntityReader.addString(piDataOffset, piDataLength);
-        fDTDGrammar.callProcessingInstruction(piTarget, piData);
-        if (fDTDHandler != null) {
-            fDTDHandler.processingInstruction(piTarget, piData);
-        }
-    }
-    //
-    // From the standard:
-    //
-    // [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
-    //                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
-    // [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl
-    //                     | NotationDecl | PI | Comment
-    //
-    // Called after scanning '<!DOCTYPE'
-    //
-    /**
-     * This routine is called after the &lt;!DOCTYPE portion of a DOCTYPE
-     * line has been called.  scanDocTypeDecl goes onto scan the rest of the DOCTYPE
-     * decl.  If an internal DTD subset exists, it is scanned. If an external DTD
-     * subset exists, scanDocTypeDecl sets up the state necessary to process it.
-     *
-     * @return true if successful
-     * @exception java.lang.Exception
-     */
-    public boolean scanDoctypeDecl() throws Exception
-    {
-        //System.out.println("XMLDTDScanner#scanDoctypeDecl()");
-
-        fDTDGrammar = new DTDGrammar(fStringPool);
-        fDTDGrammar.callStartDTD();
-        increaseMarkupDepth();
-        fEntityReader = fEntityHandler.getEntityReader();
-        fReaderId = fEntityHandler.getReaderId();
-        fDoctypeReader = fReaderId;
-        setScannerState(SCANNER_STATE_DOCTYPEDECL);
-        if (!fEntityReader.lookingAtSpace(true)) {
-            abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL,
-                        XMLMessages.P28_SPACE_REQUIRED);
-            return false;
-        }
-        fEntityReader.skipPastSpaces();
-        scanElementType(fEntityReader, ' ', fElementQName);
-        if (fElementQName.rawname == -1) {
-            abortMarkup(XMLMessages.MSG_ROOT_ELEMENT_TYPE_REQUIRED,
-                        XMLMessages.P28_ROOT_ELEMENT_TYPE_REQUIRED);
-            return false;
-        }
-        boolean lbrkt;
-        boolean scanExternalSubset = false;
-        int publicId = -1;
-        int systemId = -1;
-        if (fEntityReader.lookingAtSpace(true)) {
-            fEntityReader.skipPastSpaces();
-            if (!(lbrkt = fEntityReader.lookingAtChar('[', true)) && !fEntityReader.lookingAtChar('>', false)) {
-                if (!scanExternalID(false)) {
-                    skipPastEndOfCurrentMarkup();
-                    return false;
-                }
-                scanExternalSubset = true;
-                publicId = fPubidLiteral;
-                systemId = fSystemLiteral;
-                fEntityReader.skipPastSpaces();
-                lbrkt = fEntityReader.lookingAtChar('[', true);
-            }
-        } else
-            lbrkt = fEntityReader.lookingAtChar('[', true);
-        fDTDGrammar.doctypeDecl(fElementQName, publicId, systemId);
-        if (fDTDHandler != null) {
-            fDTDHandler.startDTD(fElementQName, publicId, systemId);
-        }
-        if (lbrkt) {
-            scanDecls(false);
-            fEntityReader.skipPastSpaces();
-        }
-        if (!fEntityReader.lookingAtChar('>', true)) {
-            if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                abortMarkup(XMLMessages.MSG_DOCTYPEDECL_UNTERMINATED,
-                            XMLMessages.P28_UNTERMINATED,
-                            fElementQName.rawname);
-            }
-            return false;
-        }
-
-        decreaseMarkupDepth();
-
-        //System.out.println("  scanExternalSubset: "+scanExternalSubset);
-        if (scanExternalSubset) {
-            ((DefaultEntityHandler) fEntityHandler).startReadingFromExternalSubset( fStringPool.toString(publicId),
-                                                                                    fStringPool.toString(systemId),
-                                                                                    markupDepth());
-            fDTDGrammar.startReadingFromExternalSubset(publicId, systemId);
-        }
-        else {
-            fDTDGrammar.callEndDTD();
-            if (fDTDHandler != null) {
-                fDTDHandler.endDTD();
-            }
-        }
-
-        fGrammarResolver.putGrammar("", fDTDGrammar);
-
-
-        return true;
-    }
-    //
-    // [75] ExternalID ::= 'SYSTEM' S SystemLiteral
-    //                     | 'PUBLIC' S PubidLiteral S SystemLiteral
-    // [83] PublicID ::= 'PUBLIC' S PubidLiteral
-    //
-    private boolean scanExternalID(boolean scanPublicID) throws Exception
-    {
-        fSystemLiteral = -1;
-        fPubidLiteral = -1;
-        int offset = fEntityReader.currentOffset();
-        if (fEntityReader.skippedString(system_string)) {
-            if (!fEntityReader.lookingAtSpace(true)) {
-                reportFatalXMLError(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_SYSTEMLITERAL_IN_EXTERNALID,
-                                    XMLMessages.P75_SPACE_REQUIRED);
-                return false;
-            }
-            fEntityReader.skipPastSpaces();
-            if( getReadingExternalEntity() == true ) {  //Are we in external subset?
-               checkForPEReference(false);//If so Check for PE Ref
-             }
-            return scanSystemLiteral();
-        }
-        if (fEntityReader.skippedString(public_string)) {
-            if (!fEntityReader.lookingAtSpace(true)) {
-                reportFatalXMLError(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_PUBIDLITERAL_IN_EXTERNALID,
-                                    XMLMessages.P75_SPACE_REQUIRED);
-                return false;
-            }
-            fEntityReader.skipPastSpaces();
-            if (!scanPubidLiteral())
-                return false;
-            if (scanPublicID) {
-                //
-                // [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
-                //
-                if (!fEntityReader.lookingAtSpace(true))
-                    return true; // no S, not an ExternalID
-                fEntityReader.skipPastSpaces();
-                if (fEntityReader.lookingAtChar('>', false)) // matches end of NotationDecl
-                    return true;
-            } else {
-                if (!fEntityReader.lookingAtSpace(true)) {
-                    reportFatalXMLError(XMLMessages.MSG_SPACE_REQUIRED_AFTER_PUBIDLITERAL_IN_EXTERNALID,
-                                        XMLMessages.P75_SPACE_REQUIRED);
-                    return false;
-                }
-                fEntityReader.skipPastSpaces();
-            }
-            return scanSystemLiteral();
-        }
-        reportFatalXMLError(XMLMessages.MSG_EXTERNALID_REQUIRED,
-                            XMLMessages.P75_INVALID);
-        return false;
-    }
-    //
-    // [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
-    //
-    // REVISIT - need to look into uri escape mechanism for non-ascii characters.
-    //
-    private boolean scanSystemLiteral() throws Exception
-    {
-        boolean single;
-        if (!(single = fEntityReader.lookingAtChar('\'', true)) && !fEntityReader.lookingAtChar('\"', true)) {
-            reportFatalXMLError(XMLMessages.MSG_QUOTE_REQUIRED_IN_SYSTEMID,
-                                XMLMessages.P11_QUOTE_REQUIRED);
-            return false;
-        }
-        int prevState = setScannerState(SCANNER_STATE_SYSTEMLITERAL);
-        int offset = fEntityReader.currentOffset();
-        char qchar = single ? '\'' : '\"';
-        boolean dataok = true;
-        boolean fragment = false;
-        while (!fEntityReader.lookingAtChar(qchar, false)) {
-//ericye
-//System.out.println("XMLDTDScanner#scanDoctypeDecl() 3333333, "+fReaderId+", " + fScannerState+", " +fExternalSubsetReader);
-            if (fEntityReader.lookingAtChar('#', true)) {
-                fragment = true;
-            } else if (!fEntityReader.lookingAtValidChar(true)) {
-//System.out.println("XMLDTDScanner#scanDoctypeDecl() 555555 scan state: " + fScannerState);
-                dataok = false;
-                int invChar = fEntityReader.scanInvalidChar();
-                if (fScannerState == SCANNER_STATE_END_OF_INPUT)
-                    return false;
-                if (invChar >= 0) {
-                    reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_SYSTEMID,
-                                        XMLMessages.P11_INVALID_CHARACTER,
-                                        Integer.toHexString(invChar));
-                }
-            }
-        }
-        if (dataok) {
-            fSystemLiteral = fEntityReader.addString(offset, fEntityReader.currentOffset() - offset);
-            if (fragment) {
-                // NOTE: RECOVERABLE ERROR
-                Object[] args = { fStringPool.toString(fSystemLiteral) };
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_URI_FRAGMENT_IN_SYSTEMID,
-                                           XMLMessages.P11_URI_FRAGMENT,
-                                           args,
-                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-            }
-        }
-        fEntityReader.lookingAtChar(qchar, true);
-        restoreScannerState(prevState);
-        return dataok;
-    }
-    //
-    // [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
-    // [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
-    //
-    private boolean scanPubidLiteral() throws Exception
-    {
-        boolean single;
-        if (!(single = fEntityReader.lookingAtChar('\'', true)) && !fEntityReader.lookingAtChar('\"', true)) {
-            reportFatalXMLError(XMLMessages.MSG_QUOTE_REQUIRED_IN_PUBLICID,
-                                XMLMessages.P12_QUOTE_REQUIRED);
-            return false;
-        }
-        char qchar = single ? '\'' : '\"';
-        int prevState = setScannerState(SCANNER_STATE_PUBIDLITERAL);
-        boolean dataok = true;
-        while (true) {
-            if (fEntityReader.lookingAtChar((char)0x09, true)) {
-                dataok = false;
-                reportFatalXMLError(XMLMessages.MSG_PUBIDCHAR_ILLEGAL,
-                                    XMLMessages.P12_INVALID_CHARACTER, "9");
-            }
-            if (!fEntityReader.lookingAtSpace(true))
-                break;
-        }
-        int offset = fEntityReader.currentOffset();
-        int dataOffset = fLiteralData.length();
-        int toCopy = offset;
-        while (true) {
-            if (fEntityReader.lookingAtChar(qchar, true)) {
-                if (dataok && offset - toCopy > 0)
-                    fEntityReader.append(fLiteralData, toCopy, offset - toCopy);
-                break;
-            }
-            if (fEntityReader.lookingAtChar((char)0x09, true)) {
-                dataok = false;
-                reportFatalXMLError(XMLMessages.MSG_PUBIDCHAR_ILLEGAL,
-                                    XMLMessages.P12_INVALID_CHARACTER, "9");
-                continue;
-            }
-            if (fEntityReader.lookingAtSpace(true)) {
-                if (dataok && offset - toCopy > 0)
-                    fEntityReader.append(fLiteralData, toCopy, offset - toCopy);
-                while (true) {
-                    if (fEntityReader.lookingAtChar((char)0x09, true)) {
-                        dataok = false;
-                        reportFatalXMLError(XMLMessages.MSG_PUBIDCHAR_ILLEGAL,
-                                            XMLMessages.P12_INVALID_CHARACTER, "9");
-                        break;
-                    } else if (!fEntityReader.lookingAtSpace(true)) {
-                        break;
-                    }
-                }
-                if (fEntityReader.lookingAtChar(qchar, true))
-                    break;
-                if (dataok) {
-                    fLiteralData.append(' ');
-                    offset = fEntityReader.currentOffset();
-                    toCopy = offset;
-                }
-                continue;
-            }
-            if (!fEntityReader.lookingAtValidChar(true)) {
-                int invChar = fEntityReader.scanInvalidChar();
-                if (fScannerState == SCANNER_STATE_END_OF_INPUT)
-                    return false;
-                dataok = false;
-                if (invChar >= 0) {
-                    reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_PUBLICID,
-                                        XMLMessages.P12_INVALID_CHARACTER,
-                                        Integer.toHexString(invChar));
-                }
-            }
-            if (dataok)
-                offset = fEntityReader.currentOffset();
-        }
-        if (dataok) {
-            int dataLength = fLiteralData.length() - dataOffset;
-            fPubidLiteral = fLiteralData.addString(dataOffset, dataLength);
-            String publicId = fStringPool.toString(fPubidLiteral);
-            int invCharIndex = validPublicId(publicId);
-            if (invCharIndex >= 0) {
-                reportFatalXMLError(XMLMessages.MSG_PUBIDCHAR_ILLEGAL,
-                                    XMLMessages.P12_INVALID_CHARACTER,
-                                    Integer.toHexString(publicId.charAt(invCharIndex)));
-                return false;
-            }
-        }
-        restoreScannerState(prevState);
-        return dataok;
-    }
-    //
-    // [??] intSubsetDecl = '[' (markupdecl | PEReference | S)* ']'
-    //
-    // [31] extSubsetDecl ::= ( markupdecl | conditionalSect | PEReference | S )*
-    // [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
-    //
-    // [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl
-    //                     | NotationDecl | PI | Comment
-    //
-    // [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
-    //
-    // [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
-    //
-    // [70] EntityDecl ::= GEDecl | PEDecl
-    // [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
-    // [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
-    //
-    // [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
-    //
-    // [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
-    //
-    // [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
-    //
-    // [61] conditionalSect ::= includeSect | ignoreSect
-    // [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
-    // [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
-    // [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
-    // [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
-    //
-    /**
-     * Scan markup declarations
-     *
-     * @param extSubset true if the scanner is scanning an external subset, false
-     *                  if it is scanning an internal subset
-     * @exception java.lang.Exception
-     */
-    public void scanDecls(boolean extSubset) throws Exception
-    {
-        int subsetOffset = fEntityReader.currentOffset();
-        if (extSubset)
-            fExternalSubsetReader = fReaderId;
-        fIncludeSectDepth = 0;
-        boolean parseTextDecl = extSubset;
-        int prevState = setScannerState(SCANNER_STATE_MARKUP_DECL);
-        while (fScannerState == SCANNER_STATE_MARKUP_DECL) {
-
-            boolean newParseTextDecl = false;
-            if (!extSubset && fEntityReader.lookingAtChar(']', false)) {
-                int subsetLength = fEntityReader.currentOffset() - subsetOffset;
-                int internalSubset = fEntityReader.addString(subsetOffset, subsetLength);
-                fDTDGrammar.internalSubset(internalSubset);
-                if (fDTDHandler != null) {
-                    fDTDHandler.internalSubset(internalSubset);
-                }
-                fEntityReader.lookingAtChar(']', true);
-                restoreScannerState(prevState);
-                return;
-            }
-            if (fEntityReader.lookingAtChar('<', true)) {
-                int olddepth = markupDepth();
-                increaseMarkupDepth();
-                if (fEntityReader.lookingAtChar('!', true)) {
-                    if (fEntityReader.lookingAtChar('-', true)) {
-                        if (fEntityReader.lookingAtChar('-', true)) {
-                            scanComment();
-                        } else {
-                            abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
-                                        XMLMessages.P29_NOT_RECOGNIZED);
-                        }
-                    } else if (fEntityReader.lookingAtChar('[', true) && getReadingExternalEntity()) {
-                        checkForPEReference(false);
-                        if (fEntityReader.skippedString(include_string)) {
-                            checkForPEReference(false);
-                            if (!fEntityReader.lookingAtChar('[', true)) {
-                                abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
-                                            XMLMessages.P29_NOT_RECOGNIZED);
-                            } else {
-                                fIncludeSectDepth++;
-                            }
-                        } else if (fEntityReader.skippedString(ignore_string)) {
-                            checkForPEReference(false);
-                            if (!fEntityReader.lookingAtChar('[', true)) {
-                                abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
-                                            XMLMessages.P29_NOT_RECOGNIZED);
-                            } else
-                                scanIgnoreSectContents();
-                        } else {
-                            abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
-                                        XMLMessages.P29_NOT_RECOGNIZED);
-                        }
-                    } else if (fEntityReader.skippedString(element_string)) {
-                        scanElementDecl();
-                    }
-                    else if (fEntityReader.skippedString(attlist_string))
-                        scanAttlistDecl();
-                    else if (fEntityReader.skippedString(entity_string))
-                        scanEntityDecl();
-                    else if (fEntityReader.skippedString(notation_string))
-                        scanNotationDecl();
-                    else {
-                        abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
-                                    XMLMessages.P29_NOT_RECOGNIZED);
-                    }
-                } else if (fEntityReader.lookingAtChar('?', true)) {
-                    int piTarget = fEntityReader.scanName(' ');
-                    if (piTarget == -1) {
-                        abortMarkup(XMLMessages.MSG_PITARGET_REQUIRED,
-                                    XMLMessages.P16_REQUIRED);
-                    } else if ("xml".equals(fStringPool.toString(piTarget))) {
-                        if (fEntityReader.lookingAtSpace(true)) {
-                            if (parseTextDecl) { // a TextDecl looks like a PI with the target 'xml'
-                                scanTextDecl();
-                            } else {
-                                abortMarkup(XMLMessages.MSG_TEXTDECL_MUST_BE_FIRST,
-                                            XMLMessages.P30_TEXTDECL_MUST_BE_FIRST);
-                            }
-                        } else { // a PI target matching 'xml'
-                            abortMarkup(XMLMessages.MSG_RESERVED_PITARGET,
-                                        XMLMessages.P17_RESERVED_PITARGET);
-                        }
-                    } else // PI
-                        scanPI(piTarget);
-                } else {
-                    abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
-                                XMLMessages.P29_NOT_RECOGNIZED);
-                }
-            } else if (fEntityReader.lookingAtSpace(true)) {
-                fEntityReader.skipPastSpaces();
-            } else if (fEntityReader.lookingAtChar('%', true)) {
-                //
-                // [69] PEReference ::= '%' Name ';'
-                //
-                int nameOffset = fEntityReader.currentOffset();
-                fEntityReader.skipPastName(';');
-                int nameLength = fEntityReader.currentOffset() - nameOffset;
-                if (nameLength == 0) {
-                    reportFatalXMLError(XMLMessages.MSG_NAME_REQUIRED_IN_PEREFERENCE,
-                                        XMLMessages.P69_NAME_REQUIRED);
-                } else if (!fEntityReader.lookingAtChar(';', true)) {
-                    reportFatalXMLError(XMLMessages.MSG_SEMICOLON_REQUIRED_IN_PEREFERENCE,
-                                        XMLMessages.P69_SEMICOLON_REQUIRED,
-                                        fEntityReader.addString(nameOffset, nameLength));
-                } else {
-                    int peNameIndex = fEntityReader.addSymbol(nameOffset, nameLength);
-                    newParseTextDecl = fEntityHandler.startReadingFromEntity(peNameIndex, markupDepth(), XMLEntityHandler.ENTITYREF_IN_DTD_AS_MARKUP);
-                }
-            } else if (fIncludeSectDepth > 0 && fEntityReader.lookingAtChar(']', true)) {
-                if (!fEntityReader.lookingAtChar(']', true) || !fEntityReader.lookingAtChar('>', true)) {
-                    abortMarkup(XMLMessages.MSG_INCLUDESECT_UNTERMINATED,
-                                XMLMessages.P62_UNTERMINATED);
-                } else
-                    decreaseMarkupDepth();
-                fIncludeSectDepth--;
-            } else {
-                if (!fEntityReader.lookingAtValidChar(false)) {
-                    int invChar = fEntityReader.scanInvalidChar();
-                    if (fScannerState == SCANNER_STATE_END_OF_INPUT)
-                        break;
-                    if (invChar >= 0) {
-                        if (!extSubset) {
-                            reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_INTERNAL_SUBSET,
-                                                XMLMessages.P28_INVALID_CHARACTER,
-                                                Integer.toHexString(invChar));
-                        } else {
-                            reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_EXTERNAL_SUBSET,
-                                                XMLMessages.P30_INVALID_CHARACTER,
-                                                Integer.toHexString(invChar));
-                        }
-                    }
-                } else {
-                    reportFatalXMLError(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
-                                        XMLMessages.P29_NOT_RECOGNIZED);
-                    fEntityReader.lookingAtValidChar(true);
-                }
-            }
-            parseTextDecl = newParseTextDecl;
-        }
-        if (extSubset) {
-
-            ((DefaultEntityHandler) fEntityHandler).stopReadingFromExternalSubset();
-
-            fDTDGrammar.stopReadingFromExternalSubset();
-            fDTDGrammar.callEndDTD();
-            if (fDTDHandler != null) {
-                fDTDHandler.endDTD();
-            }
-            // REVISIT: What should the namspace URI of a DTD be?
-            fGrammarResolver.putGrammar("", fDTDGrammar);
-        }
-    }
-    //
-    // [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
-    // [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
-    //
-    private void scanIgnoreSectContents() throws Exception
-    {
-        int initialDepth = ++fIncludeSectDepth;
-        while (true) {
-            if (fEntityReader.lookingAtChar('<', true)) {
-                //
-                // These tests are split so that we handle cases like
-                // '<<![' and '<!<![' which we might otherwise miss.
-                //
-                if (fEntityReader.lookingAtChar('!', true) && fEntityReader.lookingAtChar('[', true))
-                    fIncludeSectDepth++;
-            } else if (fEntityReader.lookingAtChar(']', true)) {
-                //
-                // The same thing goes for ']<![' and '<]]>', etc.
-                //
-                if (fEntityReader.lookingAtChar(']', true)) {
-                    while (fEntityReader.lookingAtChar(']', true)) {
-                        /* empty loop body */
-                    }
-                    if (fEntityReader.lookingAtChar('>', true)) {
-                        if (fIncludeSectDepth-- == initialDepth) {
-                            decreaseMarkupDepth();
-                            return;
-                        }
-                    }
-                }
-            } else if (!fEntityReader.lookingAtValidChar(true)) {
-                int invChar = fEntityReader.scanInvalidChar();
-                if (fScannerState == SCANNER_STATE_END_OF_INPUT)
-                    return;
-                if (invChar >= 0) {
-                    reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_IGNORESECT,
-                                        XMLMessages.P65_INVALID_CHARACTER,
-                                        Integer.toHexString(invChar));
-                }
-            }
-        }
-    }
-    //
-    // From the standard:
-    //
-    // [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
-    // [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
-    // [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'" )
-    // [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
-    //
-    private void scanTextDecl() throws Exception {
-        int version = -1;
-        int encoding = -1;
-        final int TEXTDECL_START = 0;
-        final int TEXTDECL_VERSION = 1;
-        final int TEXTDECL_ENCODING = 2;
-        final int TEXTDECL_FINISHED = 3;
-        int prevState = setScannerState(SCANNER_STATE_TEXTDECL);
-        int state = TEXTDECL_START;
-        do {
-            fEntityReader.skipPastSpaces();
-            int offset = fEntityReader.currentOffset();
-            if (state == TEXTDECL_START && fEntityReader.skippedString(version_string)) {
-                state = TEXTDECL_VERSION;
-            } else if (fEntityReader.skippedString(encoding_string)) {
-                state = TEXTDECL_ENCODING;
-            } else {
-                abortMarkup(XMLMessages.MSG_ENCODINGDECL_REQUIRED,
-                            XMLMessages.P77_ENCODINGDECL_REQUIRED);
-                restoreScannerState(prevState);
-                return;
-            }
-            int length = fEntityReader.currentOffset() - offset;
-            fEntityReader.skipPastSpaces();
-            if (!fEntityReader.lookingAtChar('=', true)) {
-                int minorCode = state == TEXTDECL_VERSION ?
-                                XMLMessages.P24_EQ_REQUIRED :
-                                XMLMessages.P80_EQ_REQUIRED;
-                abortMarkup(XMLMessages.MSG_EQ_REQUIRED_IN_TEXTDECL, minorCode,
-                            fEntityReader.addString(offset, length));
-                restoreScannerState(prevState);
-                return;
-            }
-            fEntityReader.skipPastSpaces();
-            int result = fEntityReader.scanStringLiteral();
-            switch (result) {
-            case XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED:
-            {
-                int minorCode = state == TEXTDECL_VERSION ?
-                                XMLMessages.P24_QUOTE_REQUIRED :
-                                XMLMessages.P80_QUOTE_REQUIRED;
-                abortMarkup(XMLMessages.MSG_QUOTE_REQUIRED_IN_TEXTDECL, minorCode,
-                            fEntityReader.addString(offset, length));
-                restoreScannerState(prevState);
-                return;
-            }
-            case XMLEntityHandler.STRINGLIT_RESULT_INVALID_CHAR:
-                int invChar = fEntityReader.scanInvalidChar();
-                if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                    if (invChar >= 0) {
-                        int minorCode = state == TEXTDECL_VERSION ?
-                                        XMLMessages.P26_INVALID_CHARACTER :
-                                        XMLMessages.P81_INVALID_CHARACTER;
-                        reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_TEXTDECL, minorCode,
-                                            Integer.toHexString(invChar));
-                    }
-                    skipPastEndOfCurrentMarkup();
-                    restoreScannerState(prevState);
-                }
-                return;
-            default:
-                break;
-            }
-            switch (state) {
-            case TEXTDECL_VERSION:
-                //
-                // version="..."
-                //
-                version = result;
-                String versionString = fStringPool.toString(version);
-                if (!"1.0".equals(versionString)) {
-                    if (!validVersionNum(versionString)) {
-                        abortMarkup(XMLMessages.MSG_VERSIONINFO_INVALID,
-                                    XMLMessages.P26_INVALID_VALUE,
-                                    versionString);
-                        restoreScannerState(prevState);
-                        return;
-                    }
-                    // NOTE: RECOVERABLE ERROR
-                    Object[] args = { versionString };
-                    fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                               XMLMessages.XML_DOMAIN,
-                                               XMLMessages.MSG_VERSION_NOT_SUPPORTED,
-                                               XMLMessages.P26_NOT_SUPPORTED,
-                                               args,
-                                               XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                    // REVISIT - hope it is a compatible version...
-                    // skipPastEndOfCurrentMarkup();
-                    // return;
-                }
-                if (!fEntityReader.lookingAtSpace(true)) {
-                    abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_IN_TEXTDECL,
-                                XMLMessages.P80_WHITESPACE_REQUIRED);
-                    restoreScannerState(prevState);
-                    return;
-                }
-                break;
-            case TEXTDECL_ENCODING:
-                //
-                // encoding = "..."
-                //
-                encoding = result;
-                String encodingString = fStringPool.toString(encoding);
-                if (!validEncName(encodingString)) {
-                    abortMarkup(XMLMessages.MSG_ENCODINGDECL_INVALID,
-                                XMLMessages.P81_INVALID_VALUE,
-                                encodingString);
-                    restoreScannerState(prevState);
-                    return;
-                }
-                fEntityReader.skipPastSpaces();
-                state = TEXTDECL_FINISHED;
-                break;
-            }
-        } while (state != TEXTDECL_FINISHED);
-        if (!fEntityReader.lookingAtChar('?', true) || !fEntityReader.lookingAtChar('>', true)) {
-            abortMarkup(XMLMessages.MSG_TEXTDECL_UNTERMINATED,
-                        XMLMessages.P77_UNTERMINATED);
-            restoreScannerState(prevState);
-            return;
-        }
-        decreaseMarkupDepth();
-        fDTDGrammar.callTextDecl(version, encoding);
-        if (fDTDHandler != null) {
-            fDTDHandler.textDecl(version, encoding);
-        }
-        restoreScannerState(prevState);
-    }
-
-    private QName fElementDeclQName = new QName();
-
-    /**
-     * Scans an element declaration.
-     * <pre>
-     * [45] elementdecl ::= '&lt;!ELEMENT' S Name S contentspec S? '&gt;'
-     * </pre>
-     */
-    private void scanElementDecl() throws Exception {
-        
-        if (!checkForPEReference(true)) {
-            abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ELEMENTDECL,
-                        XMLMessages.P45_SPACE_REQUIRED);
-            return;
-        }
-        checkForElementTypeWithPEReference(fEntityReader, ' ', fElementQName);
-        if (fElementQName.rawname == -1) {
-            abortMarkup(XMLMessages.MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL,
-                        XMLMessages.P45_ELEMENT_TYPE_REQUIRED);
-            return;
-        }
-        if (fDTDHandler != null) {
-            fElementDeclQName.setValues(fElementQName);
-        }
-        if (!checkForPEReference(true)) {
-            abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_CONTENTSPEC_IN_ELEMENTDECL,
-                        XMLMessages.P45_SPACE_REQUIRED,
-                        fElementQName.rawname);
-            return;
-        }
-        int contentSpecType = -1;
-        int contentSpec = -1;
-        if (fEntityReader.skippedString(empty_string)) {
-            contentSpecType = XMLElementDecl.TYPE_EMPTY;
-        } else if (fEntityReader.skippedString(any_string)) {
-            contentSpecType = XMLElementDecl.TYPE_ANY;
-        } else if (!fEntityReader.lookingAtChar('(', true)) {
-            abortMarkup(XMLMessages.MSG_CONTENTSPEC_REQUIRED_IN_ELEMENTDECL,
-                        XMLMessages.P45_CONTENTSPEC_REQUIRED,
-                        fElementQName.rawname);
-            return;
-        } else {
-            int contentSpecReader = fReaderId;
-            int contentSpecReaderDepth = fEntityHandler.getReaderDepth();
-            int prevState = setScannerState(SCANNER_STATE_CONTENTSPEC);
-            int oldDepth = parenDepth();
-            fEntityHandler.setReaderDepth(oldDepth);
-            increaseParenDepth();
-            checkForPEReference(false);
-            boolean skippedPCDATA = fEntityReader.skippedString(pcdata_string);
-            if (skippedPCDATA) {
-                contentSpecType = XMLElementDecl.TYPE_MIXED;
-                // REVISIT: Validation. Should we pass in QName?
-                contentSpec = scanMixed(fElementQName);
-            } else {
-                contentSpecType = XMLElementDecl.TYPE_CHILDREN;
-                // REVISIT: Validation. Should we pass in QName?
-                contentSpec = scanChildren(fElementQName);
-            }
-            boolean success = contentSpec != -1;
-            restoreScannerState(prevState);
-            fEntityHandler.setReaderDepth(contentSpecReaderDepth);
-            if (!success) {
-                setParenDepth(oldDepth);
-                skipPastEndOfCurrentMarkup();
-                return;
-            } else {
-                if (parenDepth() != oldDepth) // REVISIT - should not be needed
-                    // System.out.println("nesting depth mismatch");
-                    ;
-            }
-        }
-        checkForPEReference(false);
-        if (!fEntityReader.lookingAtChar('>', true)) {
-            abortMarkup(XMLMessages.MSG_ELEMENTDECL_UNTERMINATED,
-                        XMLMessages.P45_UNTERMINATED,
-                        fElementQName.rawname);
-            return;
-        }
-        decreaseMarkupDepth();
-        int elementIndex = fDTDGrammar.getElementDeclIndex(fElementQName, -1);
-        boolean elementDeclIsExternal = getReadingExternalEntity();
-        if (elementIndex == -1) {
-            elementIndex = fDTDGrammar.addElementDecl(fElementQName, contentSpecType, contentSpec, elementDeclIsExternal);
-            //System.out.println("XMLDTDScanner#scanElementDecl->DTDGrammar#addElementDecl: "+elementIndex+" ("+fElementQName.localpart+","+fStringPool.toString(fElementQName.localpart)+')');
-        }
-        else {
-            //now check if we already add this element Decl by foward reference
-            fDTDGrammar.getElementDecl(elementIndex, fTempElementDecl);
-            if (fTempElementDecl.type == -1) {
-                fTempElementDecl.type = contentSpecType;
-                fTempElementDecl.contentSpecIndex = contentSpec;
-                fDTDGrammar.setElementDeclDTD(elementIndex, fTempElementDecl);
-                fDTDGrammar.setElementDeclIsExternal(elementIndex, elementDeclIsExternal);
-            }
-            else {
-                //REVISIT, valiate VC duplicate element type. 
-                if ( fValidationEnabled )
-                    //&& 
-                    // (elemenetDeclIsExternal==fDTDGrammar.getElementDeclIsExternal(elementIndex)
-                {
-
-                    reportRecoverableXMLError(
-                        XMLMessages.MSG_ELEMENT_ALREADY_DECLARED,
-                        XMLMessages.VC_UNIQUE_ELEMENT_TYPE_DECLARATION,
-                        fStringPool.toString(fElementQName.rawname)
-                        );
-                }
-            }
-        }
-        if (fDTDHandler != null) {
-            fDTDGrammar.getElementDecl(elementIndex, fTempElementDecl);
-            fDTDHandler.elementDecl(fElementDeclQName, contentSpecType, contentSpec, fDTDGrammar);
-        }
-
-    } // scanElementDecl()
-
-    
-    /**
-     * Scans mixed content model. Called after scanning past '(' S? '#PCDATA'
-     * <pre>
-     * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')'
-     * </pre>
-     */
-    private int scanMixed(QName element) throws Exception {
-
-        int valueIndex = -1;  // -1 is special value for #PCDATA
-        int prevNodeIndex = -1;
-        boolean starRequired = false;
-        int[] valueSeen = new int[32];
-        int valueCount = 0;
-        boolean dupAttrType = false;
-        int nodeIndex = -1;
-
-        while (true) {
-            if (fValidationEnabled) {
-                for (int i=0; i<valueCount;i++) {
-                    if ( valueSeen[i] == valueIndex) {
-                        dupAttrType = true;
-                        break;
-                    }
-                }
-            }
-            if (dupAttrType && fValidationEnabled) {
-                reportRecoverableXMLError(XMLMessages.MSG_DUPLICATE_TYPE_IN_MIXED_CONTENT,
-                                          XMLMessages.VC_NO_DUPLICATE_TYPES,
-                                          valueIndex);
-                dupAttrType = false;
-
-            }
-            else {
-                try {
-                    valueSeen[valueCount] = valueIndex;
-                }
-                catch (ArrayIndexOutOfBoundsException ae) {
-                    int[] newArray = new int[valueSeen.length*2];
-                    System.arraycopy(valueSeen,0,newArray,0,valueSeen.length);
-                    valueSeen = newArray;
-                    valueSeen[valueCount] = valueIndex;
-                }
-                valueCount++;
-
-                nodeIndex = fDTDGrammar.addUniqueLeafNode(valueIndex);
-            }
-
-            checkForPEReference(false);
-            if (!fEntityReader.lookingAtChar('|', true)) {
-                if (!fEntityReader.lookingAtChar(')', true)) {
-                    reportFatalXMLError(XMLMessages.MSG_CLOSE_PAREN_REQUIRED_IN_MIXED,
-                                        XMLMessages.P51_CLOSE_PAREN_REQUIRED,
-                                        element.rawname);
-                    return -1;
-                }
-                decreaseParenDepth();
-                if (nodeIndex == -1) {
-                    nodeIndex = prevNodeIndex;
-                } else if (prevNodeIndex != -1) {
-                    nodeIndex = fDTDGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE, prevNodeIndex, nodeIndex);
-                }
-                if (fEntityReader.lookingAtChar('*', true)) {
-                    nodeIndex = fDTDGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE, nodeIndex);
-                } else if (starRequired) {
-                    reportFatalXMLError(XMLMessages.MSG_MIXED_CONTENT_UNTERMINATED,
-                                        XMLMessages.P51_UNTERMINATED,
-                                        fStringPool.toString(element.rawname),
-                                        fDTDGrammar.getContentSpecNodeAsString(nodeIndex));
-                    return -1;
-                }
-                return nodeIndex;
-            }
-            if (nodeIndex != -1) {
-                if (prevNodeIndex != -1) {
-                    nodeIndex = fDTDGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE, prevNodeIndex, nodeIndex);
-                }
-                prevNodeIndex = nodeIndex;
-            }
-            starRequired = true;
-            checkForPEReference(false);
-            checkForElementTypeWithPEReference(fEntityReader, ')', fElementRefQName);
-            valueIndex = fElementRefQName.rawname;
-            if (valueIndex == -1) {
-                reportFatalXMLError(XMLMessages.MSG_ELEMENT_TYPE_REQUIRED_IN_MIXED_CONTENT,
-                                    XMLMessages.P51_ELEMENT_TYPE_REQUIRED,
-                                    element.rawname);
-                return -1;
-            }
-        }
-
-    } // scanMixed(QName):int
-    
-    /**
-     * Scans a children content model.
-     * <pre>
-     * [47] children ::= (choice | seq) ('?' | '*' | '+')?
-     * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
-     * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
-     * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
-     * </pre>
-     */
-    private int scanChildren(QName element) throws Exception {
-        
-        int depth = 1;
-        initializeContentModelStack(depth);
-        while (true) {
-            if (fEntityReader.lookingAtChar('(', true)) {
-                increaseParenDepth();
-                checkForPEReference(false);
-                depth++;
-                initializeContentModelStack(depth);
-                continue;
-            }
-            checkForElementTypeWithPEReference(fEntityReader, ')', fElementRefQName);
-            int valueIndex = fElementRefQName.rawname;
-            if (valueIndex == -1) {
-                reportFatalXMLError(XMLMessages.MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN,
-                                    XMLMessages.P47_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED,
-                                    element.rawname);
-                return -1;
-            }
-            fNodeIndexStack[depth] = fDTDGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_LEAF, valueIndex);
-            if (fEntityReader.lookingAtChar('?', true)) {
-                fNodeIndexStack[depth] = fDTDGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE, fNodeIndexStack[depth]);
-            } else if (fEntityReader.lookingAtChar('*', true)) {
-                fNodeIndexStack[depth] = fDTDGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE, fNodeIndexStack[depth]);
-            } else if (fEntityReader.lookingAtChar('+', true)) {
-                fNodeIndexStack[depth] = fDTDGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE, fNodeIndexStack[depth]);
-            }
-            while (true) {
-                checkForPEReference(false);
-                if (fOpStack[depth] != XMLContentSpec.CONTENTSPECNODE_SEQ && fEntityReader.lookingAtChar('|', true)) {
-                    if (fPrevNodeIndexStack[depth] != -1) {
-                        fNodeIndexStack[depth] = fDTDGrammar.addContentSpecNode(fOpStack[depth], fPrevNodeIndexStack[depth], fNodeIndexStack[depth]);
-                    }
-                    fPrevNodeIndexStack[depth] = fNodeIndexStack[depth];
-                    fOpStack[depth] = XMLContentSpec.CONTENTSPECNODE_CHOICE;
-                    break;
-                } else if (fOpStack[depth] != XMLContentSpec.CONTENTSPECNODE_CHOICE && fEntityReader.lookingAtChar(',', true)) {
-                    if (fPrevNodeIndexStack[depth] != -1) {
-                        fNodeIndexStack[depth] = fDTDGrammar.addContentSpecNode(fOpStack[depth], fPrevNodeIndexStack[depth], fNodeIndexStack[depth]);
-                    }
-                    fPrevNodeIndexStack[depth] = fNodeIndexStack[depth];
-                    fOpStack[depth] = XMLContentSpec.CONTENTSPECNODE_SEQ;
-                    break;
-                } else {
-                    if (!fEntityReader.lookingAtChar(')', true)) {
-                        reportFatalXMLError(XMLMessages.MSG_CLOSE_PAREN_REQUIRED_IN_CHILDREN,
-                                            XMLMessages.P47_CLOSE_PAREN_REQUIRED,
-                                            element.rawname);
-                    }
-                    decreaseParenDepth();
-                    if (fPrevNodeIndexStack[depth] != -1) {
-                        fNodeIndexStack[depth] = fDTDGrammar.addContentSpecNode(fOpStack[depth], fPrevNodeIndexStack[depth], fNodeIndexStack[depth]);
-                    }
-                    int nodeIndex = fNodeIndexStack[depth--];
-                    fNodeIndexStack[depth] = nodeIndex;
-                    if (fEntityReader.lookingAtChar('?', true)) {
-                        fNodeIndexStack[depth] = fDTDGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE, fNodeIndexStack[depth]);
-                    } else if (fEntityReader.lookingAtChar('*', true)) {
-                        fNodeIndexStack[depth] = fDTDGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE, fNodeIndexStack[depth]);
-                    } else if (fEntityReader.lookingAtChar('+', true)) {
-                        fNodeIndexStack[depth] = fDTDGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE, fNodeIndexStack[depth]);
-                    }
-                    if (depth == 0) {
-                        return fNodeIndexStack[0];
-                    }
-                }
-            }
-            checkForPEReference(false);
-        }
-
-    } // scanChildren(QName):int
-
-    //
-    // [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
-    // [53] AttDef ::= S Name S AttType S DefaultDecl
-    // [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
-    //
-    private void scanAttlistDecl() throws Exception
-    {
-        if (!checkForPEReference(true)) {
-            abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ATTLISTDECL,
-                        XMLMessages.P52_SPACE_REQUIRED);
-            return;
-        }
-        checkForElementTypeWithPEReference(fEntityReader, ' ', fElementQName);
-        int elementTypeIndex = fElementQName.rawname;
-        if (elementTypeIndex == -1) {
-            abortMarkup(XMLMessages.MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL,
-                        XMLMessages.P52_ELEMENT_TYPE_REQUIRED);
-            return;
-        }
-        int elementIndex = fDTDGrammar.getElementDeclIndex(fElementQName, -1);
-        if (elementIndex == -1) {
-            elementIndex = fDTDGrammar.addElementDecl(fElementQName);
-            //System.out.println("XMLDTDScanner#scanAttListDecl->DTDGrammar#addElementDecl: "+elementIndex+" ("+fElementQName.localpart+","+fStringPool.toString(fElementQName.localpart)+')');
-        }
-        boolean sawSpace = checkForPEReference(true);
-        if (fEntityReader.lookingAtChar('>', true)) {
-            decreaseMarkupDepth();
-            return;
-        }
-        // REVISIT - review this code...
-        if (!sawSpace) {
-            if (fEntityReader.lookingAtSpace(true)) {
-                fEntityReader.skipPastSpaces();
-            } else
-                reportFatalXMLError(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ATTRIBUTE_NAME_IN_ATTDEF,
-                                    XMLMessages.P53_SPACE_REQUIRED);
-        } else {
-            if (fEntityReader.lookingAtSpace(true)) {
-                fEntityReader.skipPastSpaces();
-            }
-        }
-        if (fEntityReader.lookingAtChar('>', true)) {
-            decreaseMarkupDepth();
-            return;
-        }
-        while (true) {
-            checkForAttributeNameWithPEReference(fEntityReader, ' ', fAttributeQName);
-            int attDefName = fAttributeQName.rawname;
-            if (attDefName == -1) {
-                abortMarkup(XMLMessages.MSG_ATTRIBUTE_NAME_REQUIRED_IN_ATTDEF,
-                            XMLMessages.P53_NAME_REQUIRED,
-                            fElementQName.rawname);
-                return;
-            }
-            if (!checkForPEReference(true)) {
-                abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ATTTYPE_IN_ATTDEF,
-                            XMLMessages.P53_SPACE_REQUIRED);
-                return;
-            }
-            int attDefType = -1;
-            boolean attDefList = false;
-            int attDefEnumeration = -1;
-            if (fEntityReader.skippedString(cdata_string)) {
-                attDefType = XMLAttributeDecl.TYPE_CDATA;
-            } else if (fEntityReader.skippedString(id_string)) {
-                if (!fEntityReader.skippedString(ref_string)) {
-                    attDefType = XMLAttributeDecl.TYPE_ID;
-                } else if (!fEntityReader.lookingAtChar('S', true)) {
-                    attDefType = XMLAttributeDecl.TYPE_IDREF;
-                } else {
-                    attDefType = XMLAttributeDecl.TYPE_IDREF;
-                    attDefList = true;
-                }
-            } else if (fEntityReader.skippedString(entit_string)) {
-                if (fEntityReader.lookingAtChar('Y', true)) {
-                    attDefType = XMLAttributeDecl.TYPE_ENTITY;
-                } else if (fEntityReader.skippedString(ies_string)) {
-                    attDefType = XMLAttributeDecl.TYPE_ENTITY;
-                    attDefList = true;
-                } else {
-                    abortMarkup(XMLMessages.MSG_ATTTYPE_REQUIRED_IN_ATTDEF,
-                                XMLMessages.P53_ATTTYPE_REQUIRED,
-                                elementTypeIndex, attDefName);
-                    return;
-                }
-            } else if (fEntityReader.skippedString(nmtoken_string)) {
-                if (fEntityReader.lookingAtChar('S', true)) {
-                    attDefType = XMLAttributeDecl.TYPE_NMTOKEN;
-                    attDefList = true;
-                } else {
-                    attDefType = XMLAttributeDecl.TYPE_NMTOKEN;
-                }
-            } else if (fEntityReader.skippedString(notation_string)) {
-                if (!checkForPEReference(true)) {
-                    abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_AFTER_NOTATION_IN_NOTATIONTYPE,
-                                XMLMessages.P58_SPACE_REQUIRED,
-                                elementTypeIndex, attDefName);
-                    return;
-                }
-                if (!fEntityReader.lookingAtChar('(', true)) {
-                    abortMarkup(XMLMessages.MSG_OPEN_PAREN_REQUIRED_IN_NOTATIONTYPE,
-                                XMLMessages.P58_OPEN_PAREN_REQUIRED,
-                                elementTypeIndex, attDefName);
-                    return;
-                }
-                increaseParenDepth();
-                attDefType = XMLAttributeDecl.TYPE_NOTATION;
-                attDefEnumeration = scanEnumeration(elementTypeIndex, attDefName, true);
-                if (attDefEnumeration == -1) {
-                    skipPastEndOfCurrentMarkup();
-                    return;
-                }
-            } else if (fEntityReader.lookingAtChar('(', true)) {
-                increaseParenDepth();
-                attDefType = XMLAttributeDecl.TYPE_ENUMERATION;
-                attDefEnumeration = scanEnumeration(elementTypeIndex, attDefName, false);
-                if (attDefEnumeration == -1) {
-                    skipPastEndOfCurrentMarkup();
-                    return;
-                }
-            } else {
-                abortMarkup(XMLMessages.MSG_ATTTYPE_REQUIRED_IN_ATTDEF,
-                            XMLMessages.P53_ATTTYPE_REQUIRED,
-                            elementTypeIndex, attDefName);
-                return;
-            }
-            if (!checkForPEReference(true)) {
-                abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_DEFAULTDECL_IN_ATTDEF,
-                            XMLMessages.P53_SPACE_REQUIRED,
-                            elementTypeIndex, attDefName);
-                return;
-            }
-            int attDefDefaultType = -1;
-            int attDefDefaultValue = -1;
-            if (fEntityReader.skippedString(required_string)) {
-                attDefDefaultType = XMLAttributeDecl.DEFAULT_TYPE_REQUIRED;
-            } else if (fEntityReader.skippedString(implied_string)) {
-                attDefDefaultType = XMLAttributeDecl.DEFAULT_TYPE_IMPLIED;
-            } else {
-                if (fEntityReader.skippedString(fixed_string)) {
-                    if (!fEntityReader.lookingAtSpace(true)) {
-                        abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_AFTER_FIXED_IN_DEFAULTDECL,
-                                    XMLMessages.P60_SPACE_REQUIRED,
-                                    elementTypeIndex, attDefName);
-                        return;
-                    }
-                    fEntityReader.skipPastSpaces();
-                    attDefDefaultType = XMLAttributeDecl.DEFAULT_TYPE_FIXED;
-                } else
-                    attDefDefaultType = XMLAttributeDecl.DEFAULT_TYPE_DEFAULT;
-
-                //fElementQName.setValues(-1, elementTypeIndex, elementTypeIndex);
-
-                // if attribute name has a prefix "xml", bind it to the XML Namespace.
-                // since this is the only pre-defined namespace.
-                /***
-                if (fAttributeQName.prefix == fXMLSymbol) {
-                    fAttributeQName.uri = fXMLNamespace;
-                }
-                else 
-                    fAttributeQName.setValues(-1, attDefName, attDefName);
-                ****/
-
-                attDefDefaultValue = scanDefaultAttValue(fElementQName, fAttributeQName, 
-                                                         attDefType, 
-                                                         attDefEnumeration);
-
-                //normalize and check VC: Attribute Default Legal
-                if (attDefDefaultValue != -1 && attDefType != XMLAttributeDecl.TYPE_CDATA ) {
-                    attDefDefaultValue = normalizeDefaultAttValue( fAttributeQName, attDefDefaultValue, 
-                                                                attDefType, attDefEnumeration,
-                                                                attDefList);
-                }
-
-                if (attDefDefaultValue == -1) {
-                    skipPastEndOfCurrentMarkup();
-                    return;
-                }
-            }
-            if (attDefName == fXMLSpace) {
-                boolean ok = false;
-                if (attDefType == XMLAttributeDecl.TYPE_ENUMERATION) {
-                    int index = attDefEnumeration;
-                    if (index != -1) {
-                        ok = (fStringPool.stringListLength(index) == 1 &&
-                              (fStringPool.stringInList(index, fDefault) ||
-                               fStringPool.stringInList(index, fPreserve))) ||
-                            (fStringPool.stringListLength(index) == 2 &&
-                             fStringPool.stringInList(index, fDefault) &&
-                             fStringPool.stringInList(index, fPreserve));
-                    }
-                }
-                if (!ok) {
-                    reportFatalXMLError(XMLMessages.MSG_XML_SPACE_DECLARATION_ILLEGAL,
-                                        XMLMessages.S2_10_DECLARATION_ILLEGAL,
-                                        elementTypeIndex);
-                }
-            }
-            sawSpace = checkForPEReference(true);
-            
-            // if attribute name has a prefix "xml", bind it to the XML Namespace.
-            // since this is the only pre-defined namespace.
-            if (fAttributeQName.prefix == fXMLSymbol) {
-                fAttributeQName.uri = fXMLNamespace;
-            }
-            
-            if (fEntityReader.lookingAtChar('>', true)) {
-                int attDefIndex = addAttDef(fElementQName, fAttributeQName, 
-                                                        attDefType, attDefList, attDefEnumeration, 
-                                                        attDefDefaultType, attDefDefaultValue, 
-                                                        getReadingExternalEntity());
-                //System.out.println("XMLDTDScanner#scanAttlistDecl->DTDGrammar#addAttDef: "+attDefIndex+
-                //                   " ("+fElementQName.localpart+","+fStringPool.toString(fElementQName.rawname)+')'+
-                //                   " ("+fAttributeQName.localpart+","+fStringPool.toString(fAttributeQName.rawname)+')');
-                decreaseMarkupDepth();
-                return;
-            }
-            // REVISIT - review this code...
-            if (!sawSpace) {
-                if (fEntityReader.lookingAtSpace(true)) {
-                    fEntityReader.skipPastSpaces();
-                } else
-                    reportFatalXMLError(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ATTRIBUTE_NAME_IN_ATTDEF,
-                                        XMLMessages.P53_SPACE_REQUIRED);
-            } else {
-                if (fEntityReader.lookingAtSpace(true)) {
-                    fEntityReader.skipPastSpaces();
-                }
-            }
-            if (fEntityReader.lookingAtChar('>', true)) {
-                int attDefIndex = addAttDef(fElementQName, fAttributeQName, 
-                                                        attDefType, attDefList, attDefEnumeration, 
-                                                        attDefDefaultType, attDefDefaultValue,
-                                                        getReadingExternalEntity() );
-                //System.out.println("XMLDTDScanner#scanAttlistDecl->DTDGrammar#addAttDef: "+attDefIndex+
-                //                   " ("+fElementQName.localpart+","+fStringPool.toString(fElementQName.rawname)+')'+
-                //                   " ("+fAttributeQName.localpart+","+fStringPool.toString(fAttributeQName.rawname)+')');
-                decreaseMarkupDepth();
-                return;
-            }
-            int attDefIndex = addAttDef(fElementQName, fAttributeQName, 
-                                                    attDefType, attDefList, attDefEnumeration, 
-                                                    attDefDefaultType, attDefDefaultValue,
-                                                    getReadingExternalEntity());
-            //System.out.println("XMLDTDScanner#scanAttlistDecl->DTDGrammar#addAttDef: "+attDefIndex+
-            //                   " ("+fElementQName.localpart+","+fStringPool.toString(fElementQName.rawname)+')'+
-            //                   " ("+fAttributeQName.localpart+","+fStringPool.toString(fAttributeQName.rawname)+')');
-        }
-    }
-
-    private int addAttDef(QName element, QName attribute, 
-                          int attDefType, boolean attDefList, int attDefEnumeration, 
-                          int attDefDefaultType, int attDefDefaultValue,
-                          boolean isExternal ) throws Exception {
-
-        if (fDTDHandler != null) {
-            String enumString = attDefEnumeration != -1 ? fStringPool.stringListAsString(attDefEnumeration) : null;
-            fDTDHandler.attlistDecl(element, attribute, 
-                                    attDefType, attDefList,
-                                    enumString, 
-                                    attDefDefaultType, attDefDefaultValue);
-        }
-        int elementIndex = fDTDGrammar.getElementDeclIndex(element, -1);
-        if (elementIndex == -1) {
-            // REPORT Internal error here
-        }
-        else {
-            int attlistIndex = fDTDGrammar.getFirstAttributeDeclIndex(elementIndex);
-            int dupID = -1;
-            int dupNotation = -1;
-            while (attlistIndex != -1) {
-                fDTDGrammar.getAttributeDecl(attlistIndex, fTempAttributeDecl);
-
-                // REVISIT: Validation. Attributes are also tuples.
-                if (fStringPool.equalNames(fTempAttributeDecl.name.rawname, attribute.rawname)) {
-                    /******
-                    if (fWarningOnDuplicateAttDef) {
-                        Object[] args = { fStringPool.toString(fElementType[elemChunk][elemIndex]),
-                                          fStringPool.toString(attributeDecl.rawname) };
-                        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                                   XMLMessages.XML_DOMAIN,
-                                                   XMLMessages.MSG_DUPLICATE_ATTDEF,
-                                                   XMLMessages.P53_DUPLICATE,
-                                                   args,
-                                                   XMLErrorReporter.ERRORTYPE_WARNING);
-                    }
-                    ******/
-                    return -1;
-                }
-
-                if (fValidationEnabled) {
-                    if (attDefType == XMLAttributeDecl.TYPE_ID && 
-                        fTempAttributeDecl.type == XMLAttributeDecl.TYPE_ID ) {
-                        dupID = fTempAttributeDecl.name.rawname;
-                    }
-                    if (attDefType == XMLAttributeDecl.TYPE_NOTATION 
-                        && fTempAttributeDecl.type == XMLAttributeDecl.TYPE_NOTATION) {
-                        dupNotation = fTempAttributeDecl.name.rawname;
-                    }
-                }
-                attlistIndex = fDTDGrammar.getNextAttributeDeclIndex(attlistIndex);
-            }
-            if (fValidationEnabled) {
-                if (dupID != -1) {
-                    Object[] args = { fStringPool.toString(element.rawname),
-                                      fStringPool.toString(dupID),
-                                      fStringPool.toString(attribute.rawname) };
-                    fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                               XMLMessages.XML_DOMAIN,
-                                               XMLMessages.MSG_MORE_THAN_ONE_ID_ATTRIBUTE,
-                                               XMLMessages.VC_ONE_ID_PER_ELEMENT_TYPE,
-                                               args,
-                                               XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                    return -1;
-                }
-                if (dupNotation != -1) {
-                    Object[] args = { fStringPool.toString(element.rawname),
-                                      fStringPool.toString(dupNotation),
-                                      fStringPool.toString(attribute.rawname) };
-                    fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                               XMLMessages.XML_DOMAIN,
-                                               XMLMessages.MSG_MORE_THAN_ONE_NOTATION_ATTRIBUTE,
-                                               XMLMessages.VC_ONE_NOTATION_PER_ELEMENT_TYPE,
-                                               args,
-                                               XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                    return -1;
-                }
-            }
-        }
-        return fDTDGrammar.addAttDef(element, attribute, 
-                                     attDefType, attDefList, attDefEnumeration, 
-                                     attDefDefaultType, attDefDefaultValue,
-                                     isExternal);
-
-    }
-    //
-    // [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
-    // [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
-    //
-    private int scanEnumeration(int elementType, int attrName, boolean isNotationType) throws Exception
-    {
-        int enumIndex = fDTDGrammar.startEnumeration();
-        while (true) {
-            checkForPEReference(false);
-            int nameIndex = isNotationType ?
-                            checkForNameWithPEReference(fEntityReader, ')') :
-                            checkForNmtokenWithPEReference(fEntityReader, ')');
-            if (nameIndex == -1) {
-                if (isNotationType) {
-                    reportFatalXMLError(XMLMessages.MSG_NAME_REQUIRED_IN_NOTATIONTYPE,
-                                        XMLMessages.P58_NAME_REQUIRED,
-                                        elementType,
-                                        attrName);
-                } else {
-                    reportFatalXMLError(XMLMessages.MSG_NMTOKEN_REQUIRED_IN_ENUMERATION,
-                                        XMLMessages.P59_NMTOKEN_REQUIRED,
-                                        elementType,
-                                        attrName);
-                }
-                fDTDGrammar.endEnumeration(enumIndex);
-                return -1;
-            }
-            fDTDGrammar.addNameToEnumeration(enumIndex, elementType, attrName, nameIndex, isNotationType);
-            /*****/
-            if (isNotationType && !((DefaultEntityHandler)fEntityHandler).isNotationDeclared(nameIndex)) {
-                Object[] args = { fStringPool.toString(elementType),
-                    fStringPool.toString(attrName),
-                    fStringPool.toString(nameIndex) };
-                    ((DefaultEntityHandler)fEntityHandler).addRequiredNotation(nameIndex,
-                                                       fErrorReporter.getLocator(),
-                                                       XMLMessages.MSG_NOTATION_NOT_DECLARED_FOR_NOTATIONTYPE_ATTRIBUTE,
-                                                       XMLMessages.VC_NOTATION_DECLARED,
-                                                       args);
-            }
-            /*****/
-            checkForPEReference(false);
-            if (!fEntityReader.lookingAtChar('|', true)) {
-                fDTDGrammar.endEnumeration(enumIndex);
-                if (!fEntityReader.lookingAtChar(')', true)) {
-                    if (isNotationType) {
-                        reportFatalXMLError(XMLMessages.MSG_NOTATIONTYPE_UNTERMINATED,
-                                            XMLMessages.P58_UNTERMINATED,
-                                        elementType,
-                                        attrName);
-                    } else {
-                        reportFatalXMLError(XMLMessages.MSG_ENUMERATION_UNTERMINATED,
-                                            XMLMessages.P59_UNTERMINATED,
-                                        elementType,
-                                        attrName);
-                    }
-                    return -1;
-                }
-                decreaseParenDepth();
-                return enumIndex;
-            }
-        }
-    }
-    //
-    // [10] AttValue ::= '"' ([^<&"] | Reference)* '"'
-    //                   | "'" ([^<&'] | Reference)* "'"
-    //
-    /**
-     * Scan the default value in an attribute declaration
-     *
-     * @param elementType handle to the element that owns the attribute
-     * @param attrName handle in the string pool for the attribute name
-     * @return handle in the string pool for the default attribute value
-     * @exception java.lang.Exception
-     */
-    public int scanDefaultAttValue(QName element, QName attribute) throws Exception
-    {
-        boolean single;
-        if (!(single = fEntityReader.lookingAtChar('\'', true)) && !fEntityReader.lookingAtChar('\"', true)) {
-            reportFatalXMLError(XMLMessages.MSG_QUOTE_REQUIRED_IN_ATTVALUE,
-                                XMLMessages.P10_QUOTE_REQUIRED,
-                                element.rawname,
-                                attribute.rawname);
-            return -1;
-        }
-        int previousState = setScannerState(SCANNER_STATE_DEFAULT_ATTRIBUTE_VALUE);
-        char qchar = single ? '\'' : '\"';
-        fDefaultAttValueReader = fReaderId;
-        fDefaultAttValueElementType = element.rawname;
-        fDefaultAttValueAttrName = attribute.rawname;
-        boolean setMark = true;
-        int dataOffset = fLiteralData.length();
-        while (true) {
-            fDefaultAttValueOffset = fEntityReader.currentOffset();
-            if (setMark) {
-                fDefaultAttValueMark = fDefaultAttValueOffset;
-                setMark = false;
-            }
-            if (fEntityReader.lookingAtChar(qchar, true)) {
-                if (fReaderId == fDefaultAttValueReader)
-                    break;
-                continue;
-            }
-            if (fEntityReader.lookingAtChar(' ', true)) {
-                continue;
-            }
-            boolean skippedCR;
-            if ((skippedCR = fEntityReader.lookingAtChar((char)0x0D, true)) || fEntityReader.lookingAtSpace(true)) {
-                if (fDefaultAttValueOffset - fDefaultAttValueMark > 0)
-                    fEntityReader.append(fLiteralData, fDefaultAttValueMark, fDefaultAttValueOffset - fDefaultAttValueMark);
-                setMark = true;
-                fLiteralData.append(' ');
-                if (skippedCR)
-                    fEntityReader.lookingAtChar((char)0x0A, true);
-                continue;
-            }
-            if (fEntityReader.lookingAtChar('&', true)) {
-                if (fDefaultAttValueOffset - fDefaultAttValueMark > 0)
-                    fEntityReader.append(fLiteralData, fDefaultAttValueMark, fDefaultAttValueOffset - fDefaultAttValueMark);
-                setMark = true;
-                //
-                // Check for character reference first.
-                //
-                if (fEntityReader.lookingAtChar('#', true)) {
-                    int ch = scanCharRef();
-                    if (ch != -1) {
-                        if (ch < 0x10000)
-                            fLiteralData.append((char)ch);
-                        else {
-                            fLiteralData.append((char)(((ch-0x00010000)>>10)+0xd800));
-                            fLiteralData.append((char)(((ch-0x00010000)&0x3ff)+0xdc00));
-                        }
-                    }
-                } else {
-                    //
-                    // Entity reference
-                    //
-                    int nameOffset = fEntityReader.currentOffset();
-                    fEntityReader.skipPastName(';');
-                    int nameLength = fEntityReader.currentOffset() - nameOffset;
-                    if (nameLength == 0) {
-                        reportFatalXMLError(XMLMessages.MSG_NAME_REQUIRED_IN_REFERENCE,
-                                            XMLMessages.P68_NAME_REQUIRED);
-                    } else if (!fEntityReader.lookingAtChar(';', true)) {
-                        reportFatalXMLError(XMLMessages.MSG_SEMICOLON_REQUIRED_IN_REFERENCE,
-                                            XMLMessages.P68_SEMICOLON_REQUIRED,
-                                            fEntityReader.addString(nameOffset, nameLength));
-                    } else {
-                        int entityNameIndex = fEntityReader.addSymbol(nameOffset, nameLength);
-                        fEntityHandler.startReadingFromEntity(entityNameIndex, markupDepth(), XMLEntityHandler.ENTITYREF_IN_DEFAULTATTVALUE);
-                    }
-                }
-                continue;
-            }
-            if (fEntityReader.lookingAtChar('<', true)) {
-                if (fDefaultAttValueOffset - fDefaultAttValueMark > 0)
-                    fEntityReader.append(fLiteralData, fDefaultAttValueMark, fDefaultAttValueOffset - fDefaultAttValueMark);
-                setMark = true;
-                reportFatalXMLError(XMLMessages.MSG_LESSTHAN_IN_ATTVALUE,
-                                    XMLMessages.WFC_NO_LESSTHAN_IN_ATTVALUE,
-                                    element.rawname,
-                                    attribute.rawname);
-                continue;
-            }
-            //
-            // REVISIT - HACK !!!  code added to pass incorrect OASIS test 'valid-sa-094'
-            //  Remove this next section to conform to the spec...
-            //
-            if (!getReadingExternalEntity() && fEntityReader.lookingAtChar('%', true)) {
-                int nameOffset = fEntityReader.currentOffset();
-                fEntityReader.skipPastName(';');
-                int nameLength = fEntityReader.currentOffset() - nameOffset;
-                if (nameLength != 0 && fEntityReader.lookingAtChar(';', true)) {
-                    reportFatalXMLError(XMLMessages.MSG_PEREFERENCE_WITHIN_MARKUP,
-                                        XMLMessages.WFC_PES_IN_INTERNAL_SUBSET,
-                                        fEntityReader.addString(nameOffset, nameLength));
-                }
-            }
-            //
-            // END HACK !!!
-            //
-            if (!fEntityReader.lookingAtValidChar(true)) {
-                if (fDefaultAttValueOffset - fDefaultAttValueMark > 0)
-                    fEntityReader.append(fLiteralData, fDefaultAttValueMark, fDefaultAttValueOffset - fDefaultAttValueMark);
-                setMark = true;
-                int invChar = fEntityReader.scanInvalidChar();
-                if (fScannerState == SCANNER_STATE_END_OF_INPUT)
-                    return -1;
-                if (invChar >= 0) {
-                    reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_ATTVALUE,
-                                        XMLMessages.P10_INVALID_CHARACTER,
-                                        fStringPool.toString(element.rawname),
-                                        fStringPool.toString(attribute.rawname),
-                                        Integer.toHexString(invChar));
-                }
-                continue;
-            }
-        }
-        restoreScannerState(previousState);
-        int dataLength = fLiteralData.length() - dataOffset;
-        if (dataLength == 0) {
-            return fEntityReader.addString(fDefaultAttValueMark, fDefaultAttValueOffset - fDefaultAttValueMark);
-        }
-        if (fDefaultAttValueOffset - fDefaultAttValueMark > 0) {
-            fEntityReader.append(fLiteralData, fDefaultAttValueMark, fDefaultAttValueOffset - fDefaultAttValueMark);
-            dataLength = fLiteralData.length() - dataOffset;
-        }
-        return fLiteralData.addString(dataOffset, dataLength);
-    }
-    //
-    // [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
-    //
-    private void scanNotationDecl() throws Exception
-    {
-        if (!checkForPEReference(true)) {
-            abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_NOTATIONDECL,
-                        XMLMessages.P82_SPACE_REQUIRED);
-            return;
-        }
-        int notationName = checkForNameWithPEReference(fEntityReader, ' ');
-        if (notationName == -1) {
-            abortMarkup(XMLMessages.MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL,
-                        XMLMessages.P82_NAME_REQUIRED);
-            return;
-        }
-        if (!checkForPEReference(true)) {
-            abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_AFTER_NOTATION_NAME_IN_NOTATIONDECL,
-                        XMLMessages.P82_SPACE_REQUIRED,
-                        notationName);
-            return;
-        }
-        if (!scanExternalID(true)) {
-            skipPastEndOfCurrentMarkup();
-            return;
-        }
-        checkForPEReference(false);
-        if (!fEntityReader.lookingAtChar('>', true)) {
-            abortMarkup(XMLMessages.MSG_NOTATIONDECL_UNTERMINATED,
-                        XMLMessages.P82_UNTERMINATED,
-                        notationName);
-            return;
-        }
-        decreaseMarkupDepth();
-        /****
-        System.out.println(fStringPool.toString(notationName)+","
-                           +fStringPool.toString(fPubidLiteral) + ","
-                           +fStringPool.toString(fSystemLiteral) + ","
-                           +getReadingExternalEntity());
-        /****/
-
-        int notationIndex = ((DefaultEntityHandler) fEntityHandler).addNotationDecl( notationName, 
-                                                                                     fPubidLiteral, 
-                                                                                     fSystemLiteral,
-                                                                                     getReadingExternalEntity());
-        fDTDGrammar.addNotationDecl(notationName, fPubidLiteral, fSystemLiteral);
-        if (fDTDHandler != null) {
-            fDTDHandler.notationDecl(notationName, fPubidLiteral, fSystemLiteral);
-        }
-    }
-    //
-    // [70] EntityDecl ::= GEDecl | PEDecl
-    // [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
-    // [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
-    // [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
-    // [74] PEDef ::= EntityValue | ExternalID
-    // [75] ExternalID ::= 'SYSTEM' S SystemLiteral
-    //                     | 'PUBLIC' S PubidLiteral S SystemLiteral
-    // [76] NDataDecl ::= S 'NDATA' S Name
-    //  [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
-    //                      | "'" ([^%&'] | PEReference | Reference)* "'"
-    //
-    // Called after scanning 'ENTITY'
-    //
-    private void scanEntityDecl() throws Exception
-    {
-        boolean isPEDecl = false;
-        boolean sawPERef = false;
-        if (fEntityReader.lookingAtSpace(true)) {
-            fEntityReader.skipPastSpaces();
-            if (!fEntityReader.lookingAtChar('%', true)) {
-                isPEDecl = false; // <!ENTITY x "x">
-            } else if (fEntityReader.lookingAtSpace(true)) {
-                checkForPEReference(false); // <!ENTITY % x "x">
-                isPEDecl = true;
-            } else if (!getReadingExternalEntity()) {
-                reportFatalXMLError(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_PEDECL,
-                                    XMLMessages.P72_SPACE);
-                isPEDecl = true;
-            } else if (fEntityReader.lookingAtChar('%', false)) {
-                checkForPEReference(false); // <!ENTITY %%x; "x"> is legal
-                isPEDecl = true;
-            } else {
-                sawPERef = true;
-            }
-        } else if (!getReadingExternalEntity() || !fEntityReader.lookingAtChar('%', true)) {
-            // <!ENTITY[^ ]...> or <!ENTITY[^ %]...>
-            reportFatalXMLError(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_ENTITYDECL,
-                                XMLMessages.P70_SPACE);
-            isPEDecl = false;
-        } else if (fEntityReader.lookingAtSpace(false)) {
-            // <!ENTITY% ...>
-            reportFatalXMLError(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_PERCENT_IN_PEDECL,
-                                XMLMessages.P72_SPACE);
-            isPEDecl = false;
-        } else {
-            sawPERef = true;
-        }
-        if (sawPERef) {
-            while (true) {
-                int nameOffset = fEntityReader.currentOffset();
-                fEntityReader.skipPastName(';');
-                int nameLength = fEntityReader.currentOffset() - nameOffset;
-                if (nameLength == 0) {
-                    reportFatalXMLError(XMLMessages.MSG_NAME_REQUIRED_IN_PEREFERENCE,
-                                        XMLMessages.P69_NAME_REQUIRED);
-                } else if (!fEntityReader.lookingAtChar(';', true)) {
-                    reportFatalXMLError(XMLMessages.MSG_SEMICOLON_REQUIRED_IN_PEREFERENCE,
-                                        XMLMessages.P69_SEMICOLON_REQUIRED,
-                                        fEntityReader.addString(nameOffset, nameLength));
-                } else {
-                    int peNameIndex = fEntityReader.addSymbol(nameOffset, nameLength);
-                    int readerDepth = (fScannerState == SCANNER_STATE_CONTENTSPEC) ? parenDepth() : markupDepth();
-                    fEntityHandler.startReadingFromEntity(peNameIndex, readerDepth, XMLEntityHandler.ENTITYREF_IN_DTD_WITHIN_MARKUP);
-                }
-                fEntityReader.skipPastSpaces();
-                if (!fEntityReader.lookingAtChar('%', true))
-                    break;
-                if (!isPEDecl) {
-                    if (fEntityReader.lookingAtSpace(true)) {
-                        checkForPEReference(false);
-                        isPEDecl = true;
-                        break;
-                    }
-                    isPEDecl = fEntityReader.lookingAtChar('%', true);
-                }
-            }
-        }
-        int entityName = checkForNameWithPEReference(fEntityReader, ' ');
-        if (entityName == -1) {
-            abortMarkup(XMLMessages.MSG_ENTITY_NAME_REQUIRED_IN_ENTITYDECL,
-                        XMLMessages.P70_REQUIRED_NAME);
-            return;
-        }
-        if (!fDTDGrammar.startEntityDecl(isPEDecl, entityName)) {
-            skipPastEndOfCurrentMarkup();
-            return;
-        }
-        if (!checkForPEReference(true)) {
-            abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_AFTER_ENTITY_NAME_IN_ENTITYDECL,
-                        XMLMessages.P70_REQUIRED_SPACE,
-                        entityName);
-            fDTDGrammar.endEntityDecl();
-            return;
-        }
-        if (isPEDecl) {
-            boolean single;
-            if ((single = fEntityReader.lookingAtChar('\'', true)) || fEntityReader.lookingAtChar('\"', true)) {
-                int value = scanEntityValue(single);
-                if (value == -1) {
-                    skipPastEndOfCurrentMarkup();
-                    fDTDGrammar.endEntityDecl();
-                    return;
-                }
-                checkForPEReference(false);
-                if (!fEntityReader.lookingAtChar('>', true)) {
-                    abortMarkup(XMLMessages.MSG_ENTITYDECL_UNTERMINATED,
-                                XMLMessages.P72_UNTERMINATED,
-                                entityName);
-                    fDTDGrammar.endEntityDecl();
-                    return;
-                }
-                decreaseMarkupDepth();
-                fDTDGrammar.endEntityDecl();
-
-                // a hack by Eric
-                //REVISIT
-                fDTDGrammar.addInternalPEDecl(entityName, value);
-                if (fDTDHandler != null) {
-                    fDTDHandler.internalPEDecl(entityName, value);
-                }
-                int entityIndex = ((DefaultEntityHandler) fEntityHandler).addInternalPEDecl(entityName, 
-                                                                                            value, 
-                                                                                            getReadingExternalEntity());
-
-            } else {
-                if (!scanExternalID(false)) {
-                    skipPastEndOfCurrentMarkup();
-                    fDTDGrammar.endEntityDecl();
-                    return;
-                }
-                checkForPEReference(false);
-                if (!fEntityReader.lookingAtChar('>', true)) {
-                    abortMarkup(XMLMessages.MSG_ENTITYDECL_UNTERMINATED,
-                                XMLMessages.P72_UNTERMINATED,
-                                entityName);
-                    fDTDGrammar.endEntityDecl();
-                    return;
-                }
-                decreaseMarkupDepth();
-                fDTDGrammar.endEntityDecl();
-
-                //a hack by Eric
-                //REVISIT
-                fDTDGrammar.addExternalPEDecl(entityName, fPubidLiteral, fSystemLiteral);
-                if (fDTDHandler != null) {
-                    fDTDHandler.externalPEDecl(entityName, fPubidLiteral, fSystemLiteral);
-                }
-                int entityIndex = ((DefaultEntityHandler) fEntityHandler).addExternalPEDecl(entityName, 
-                                                                                            fPubidLiteral, 
-                                                                                            fSystemLiteral, getReadingExternalEntity());
-            }
-        } else {
-            boolean single;
-            if ((single = fEntityReader.lookingAtChar('\'', true)) || fEntityReader.lookingAtChar('\"', true)) {
-                int value = scanEntityValue(single);
-                if (value == -1) {
-                    skipPastEndOfCurrentMarkup();
-                    fDTDGrammar.endEntityDecl();
-                    return;
-                }
-                checkForPEReference(false);
-                if (!fEntityReader.lookingAtChar('>', true)) {
-                    abortMarkup(XMLMessages.MSG_ENTITYDECL_UNTERMINATED,
-                                XMLMessages.P71_UNTERMINATED,
-                                entityName);
-                    fDTDGrammar.endEntityDecl();
-                    return;
-                }
-                decreaseMarkupDepth();
-                fDTDGrammar.endEntityDecl();
-
-                //a hack by Eric
-                //REVISIT
-                fDTDGrammar.addInternalEntityDecl(entityName, value);
-                if (fDTDHandler != null) {
-                    fDTDHandler.internalEntityDecl(entityName, value);
-                }
-                int entityIndex = ((DefaultEntityHandler) fEntityHandler).addInternalEntityDecl(entityName, 
-                                                                                                value, 
-                                                                                                getReadingExternalEntity());
-            } else {
-                if (!scanExternalID(false)) {
-                    skipPastEndOfCurrentMarkup();
-                    fDTDGrammar.endEntityDecl();
-                    return;
-                }
-                boolean unparsed = false;
-                if (fEntityReader.lookingAtSpace(true)) {
-                    fEntityReader.skipPastSpaces();
-                    unparsed = fEntityReader.skippedString(ndata_string);
-                }
-                if (!unparsed) {
-                    checkForPEReference(false);
-                    if (!fEntityReader.lookingAtChar('>', true)) {
-                        abortMarkup(XMLMessages.MSG_ENTITYDECL_UNTERMINATED,
-                                    XMLMessages.P72_UNTERMINATED,
-                                    entityName);
-                        fDTDGrammar.endEntityDecl();
-                        return;
-                    }
-                    decreaseMarkupDepth();
-                    fDTDGrammar.endEntityDecl();
-
-                    //a hack by Eric
-                    //REVISIT
-                    fDTDGrammar.addExternalEntityDecl(entityName, fPubidLiteral, fSystemLiteral);
-                    if (fDTDHandler != null) {
-                        fDTDHandler.externalEntityDecl(entityName, fPubidLiteral, fSystemLiteral);
-                    }
-                    int entityIndex = ((DefaultEntityHandler) fEntityHandler).addExternalEntityDecl(entityName, 
-                                                                                                    fPubidLiteral, 
-                                                                                                    fSystemLiteral, 
-                                                                                                    getReadingExternalEntity());
-
-                } else {
-                    if (!fEntityReader.lookingAtSpace(true)) {
-                        abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_UNPARSED_ENTITYDECL,
-                                    XMLMessages.P76_SPACE_REQUIRED,
-                                    entityName);
-                        fDTDGrammar.endEntityDecl();
-                        return;
-                    }
-                    fEntityReader.skipPastSpaces();
-                    int ndataOffset = fEntityReader.currentOffset();
-                    fEntityReader.skipPastName('>');
-                    int ndataLength = fEntityReader.currentOffset() - ndataOffset;
-                    if (ndataLength == 0) {
-                        abortMarkup(XMLMessages.MSG_NOTATION_NAME_REQUIRED_FOR_UNPARSED_ENTITYDECL,
-                                    XMLMessages.P76_REQUIRED,
-                                    entityName);
-                        fDTDGrammar.endEntityDecl();
-                        return;
-                    }
-                    int notationName = fEntityReader.addSymbol(ndataOffset, ndataLength);
-                    checkForPEReference(false);
-                    if (!fEntityReader.lookingAtChar('>', true)) {
-                        abortMarkup(XMLMessages.MSG_ENTITYDECL_UNTERMINATED,
-                                    XMLMessages.P72_UNTERMINATED,
-                                    entityName);
-                        fDTDGrammar.endEntityDecl();
-                        return;
-                    }
-                    decreaseMarkupDepth();
-                    fDTDGrammar.endEntityDecl();
-                    
-                    //a hack by Eric
-                    //REVISIT
-                    fDTDGrammar.addUnparsedEntityDecl(entityName, fPubidLiteral, fSystemLiteral, notationName);
-                    if (fDTDHandler != null) {
-                        fDTDHandler.unparsedEntityDecl(entityName, fPubidLiteral, fSystemLiteral, notationName);
-                    }
-                    /****
-                    System.out.println("----addUnparsedEntity--- "+ fStringPool.toString(entityName)+","
-                                       +fStringPool.toString(notationName)+","
-                                       +fStringPool.toString(fPubidLiteral) + ","
-                                       +fStringPool.toString(fSystemLiteral) + ","
-                                       +getReadingExternalEntity());
-                    /****/
-                    int entityIndex = ((DefaultEntityHandler) fEntityHandler).addUnparsedEntityDecl(entityName, 
-                                                                                                    fPubidLiteral, 
-                                                                                                    fSystemLiteral, 
-                                                                                                    notationName, 
-                                                                                                    getReadingExternalEntity());
-                }
-            }
-        }
-    }
-    //
-    //  [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
-    //                      | "'" ([^%&'] | PEReference | Reference)* "'"
-    //
-    private int scanEntityValue(boolean single) throws Exception
-    {
-        char qchar = single ? '\'' : '\"';
-        fEntityValueMark = fEntityReader.currentOffset();
-        int entityValue = fEntityReader.scanEntityValue(qchar, true);
-        if (entityValue < 0)
-            entityValue = scanComplexEntityValue(qchar, entityValue);
-        return entityValue;
-    }
-    private int scanComplexEntityValue(char qchar, int result) throws Exception
-    {
-        int previousState = setScannerState(SCANNER_STATE_ENTITY_VALUE);
-        fEntityValueReader = fReaderId;
-        int dataOffset = fLiteralData.length();
-        while (true) {
-            switch (result) {
-            case XMLEntityHandler.ENTITYVALUE_RESULT_FINISHED:
-            {
-                int offset = fEntityReader.currentOffset();
-                fEntityReader.lookingAtChar(qchar, true);
-                restoreScannerState(previousState);
-                int dataLength = fLiteralData.length() - dataOffset;
-                if (dataLength == 0) {
-                    return fEntityReader.addString(fEntityValueMark, offset - fEntityValueMark);
-                }
-                if (offset - fEntityValueMark > 0) {
-                    fEntityReader.append(fLiteralData, fEntityValueMark, offset - fEntityValueMark);
-                    dataLength = fLiteralData.length() - dataOffset;
-                }
-                return fLiteralData.addString(dataOffset, dataLength);
-            }
-            case XMLEntityHandler.ENTITYVALUE_RESULT_REFERENCE:
-            {
-                int offset = fEntityReader.currentOffset();
-                if (offset - fEntityValueMark > 0)
-                    fEntityReader.append(fLiteralData, fEntityValueMark, offset - fEntityValueMark);
-                fEntityReader.lookingAtChar('&', true);
-                //
-                // Check for character reference first.
-                //
-                if (fEntityReader.lookingAtChar('#', true)) {
-                    int ch = scanCharRef();
-                    if (ch != -1) {
-                        if (ch < 0x10000)
-                            fLiteralData.append((char)ch);
-                        else {
-                            fLiteralData.append((char)(((ch-0x00010000)>>10)+0xd800));
-                            fLiteralData.append((char)(((ch-0x00010000)&0x3ff)+0xdc00));
-                        }
-                    }
-                    fEntityValueMark = fEntityReader.currentOffset();
-                } else {
-                    //
-                    // Entity reference
-                    //
-                    int nameOffset = fEntityReader.currentOffset();
-                    fEntityReader.skipPastName(';');
-                    int nameLength = fEntityReader.currentOffset() - nameOffset;
-                    if (nameLength == 0) {
-                        reportFatalXMLError(XMLMessages.MSG_NAME_REQUIRED_IN_REFERENCE,
-                                            XMLMessages.P68_NAME_REQUIRED);
-                        fEntityValueMark = fEntityReader.currentOffset();
-                    } else if (!fEntityReader.lookingAtChar(';', true)) {
-                        reportFatalXMLError(XMLMessages.MSG_SEMICOLON_REQUIRED_IN_REFERENCE,
-                                            XMLMessages.P68_SEMICOLON_REQUIRED,
-                                            fEntityReader.addString(nameOffset, nameLength));
-                        fEntityValueMark = fEntityReader.currentOffset();
-                    } else {
-                        //
-                        // 4.4.7 Bypassed
-                        //
-                        // When a general entity reference appears in the EntityValue in an
-                        // entity declaration, it is bypassed and left as is.
-                        //
-                        fEntityValueMark = offset;
-                    }
-                }
-                break;
-            }
-            case XMLEntityHandler.ENTITYVALUE_RESULT_PEREF:
-            {
-                int offset = fEntityReader.currentOffset();
-                if (offset - fEntityValueMark > 0)
-                    fEntityReader.append(fLiteralData, fEntityValueMark, offset - fEntityValueMark);
-                fEntityReader.lookingAtChar('%', true);
-                int nameOffset = fEntityReader.currentOffset();
-                fEntityReader.skipPastName(';');
-                int nameLength = fEntityReader.currentOffset() - nameOffset;
-                if (nameLength == 0) {
-                    reportFatalXMLError(XMLMessages.MSG_NAME_REQUIRED_IN_PEREFERENCE,
-                                        XMLMessages.P69_NAME_REQUIRED);
-                } else if (!fEntityReader.lookingAtChar(';', true)) {
-                    reportFatalXMLError(XMLMessages.MSG_SEMICOLON_REQUIRED_IN_PEREFERENCE,
-                                        XMLMessages.P69_SEMICOLON_REQUIRED,
-                                        fEntityReader.addString(nameOffset, nameLength));
-                } else if (!getReadingExternalEntity()) {
-                    reportFatalXMLError(XMLMessages.MSG_PEREFERENCE_WITHIN_MARKUP,
-                                        XMLMessages.WFC_PES_IN_INTERNAL_SUBSET,
-                                        fEntityReader.addString(nameOffset, nameLength));
-                } else {
-                    int peNameIndex = fEntityReader.addSymbol(nameOffset, nameLength);
-                    fEntityHandler.startReadingFromEntity(peNameIndex, markupDepth(), XMLEntityHandler.ENTITYREF_IN_ENTITYVALUE);
-                }
-                fEntityValueMark = fEntityReader.currentOffset();
-                break;
-            }
-            case XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR:
-            {
-                int offset = fEntityReader.currentOffset();
-                if (offset - fEntityValueMark > 0)
-                    fEntityReader.append(fLiteralData, fEntityValueMark, offset - fEntityValueMark);
-                int invChar = fEntityReader.scanInvalidChar();
-                if (fScannerState == SCANNER_STATE_END_OF_INPUT)
-                    return -1;
-                if (invChar >= 0) {
-                    reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_ENTITYVALUE,
-                                        XMLMessages.P9_INVALID_CHARACTER,
-                                        Integer.toHexString(invChar));
-                }
-                fEntityValueMark = fEntityReader.currentOffset();
-                break;
-            }
-            case XMLEntityHandler.ENTITYVALUE_RESULT_END_OF_INPUT:
-                // all the work is done by the previous reader, just invoke the next one now.
-                break;
-            default:
-                break;
-            }
-            result = fEntityReader.scanEntityValue(fReaderId == fEntityValueReader ? qchar : -1, false);
-        }
-    }
-    //
-    //
-    //
-    private boolean checkForPEReference(boolean spaceRequired) throws Exception
-    {
-        boolean sawSpace = true;
-        if (spaceRequired)
-            sawSpace = fEntityReader.lookingAtSpace(true);
-        fEntityReader.skipPastSpaces();
-        if (!getReadingExternalEntity())
-            return sawSpace;
-        if (!fEntityReader.lookingAtChar('%', true))
-            return sawSpace;
-        while (true) {
-            int nameOffset = fEntityReader.currentOffset();
-            fEntityReader.skipPastName(';');
-            int nameLength = fEntityReader.currentOffset() - nameOffset;
-            if (nameLength == 0) {
-                reportFatalXMLError(XMLMessages.MSG_NAME_REQUIRED_IN_PEREFERENCE,
-                                    XMLMessages.P69_NAME_REQUIRED);
-            } else if (!fEntityReader.lookingAtChar(';', true)) {
-                reportFatalXMLError(XMLMessages.MSG_SEMICOLON_REQUIRED_IN_PEREFERENCE,
-                                    XMLMessages.P69_SEMICOLON_REQUIRED,
-                                    fEntityReader.addString(nameOffset, nameLength));
-            } else {
-                int peNameIndex = fEntityReader.addSymbol(nameOffset, nameLength);
-                int readerDepth = (fScannerState == SCANNER_STATE_CONTENTSPEC) ? parenDepth() : markupDepth();
-                fEntityHandler.startReadingFromEntity(peNameIndex, readerDepth, XMLEntityHandler.ENTITYREF_IN_DTD_WITHIN_MARKUP);
-            }
-            fEntityReader.skipPastSpaces();
-            if (!fEntityReader.lookingAtChar('%', true))
-                return true;
-        }
-    }
-    //
-    // content model stack
-    //
-    private void initializeContentModelStack(int depth) {
-        if (fOpStack == null) {
-            fOpStack = new int[8];
-            fNodeIndexStack = new int[8];
-            fPrevNodeIndexStack = new int[8];
-        } else if (depth == fOpStack.length) {
-            int[] newStack = new int[depth * 2];
-            System.arraycopy(fOpStack, 0, newStack, 0, depth);
-            fOpStack = newStack;
-            newStack = new int[depth * 2];
-            System.arraycopy(fNodeIndexStack, 0, newStack, 0, depth);
-            fNodeIndexStack = newStack;
-            newStack = new int[depth * 2];
-            System.arraycopy(fPrevNodeIndexStack, 0, newStack, 0, depth);
-            fPrevNodeIndexStack = newStack;
-        }
-        fOpStack[depth] = -1;
-        fNodeIndexStack[depth] = -1;
-        fPrevNodeIndexStack[depth] = -1;
-    }
-
-    private boolean validVersionNum(String version) {
-        return XMLCharacterProperties.validVersionNum(version);
-    }
-
-    private boolean validEncName(String encoding) {
-        return XMLCharacterProperties.validEncName(encoding);
-    }
-
-    private int validPublicId(String publicId) {
-        return XMLCharacterProperties.validPublicId(publicId);
-    }
-
-    private void scanElementType(XMLEntityHandler.EntityReader entityReader, 
-                                char fastchar, QName element) throws Exception {
-
-        if (!fNamespacesEnabled) {
-            element.clear();
-            element.localpart = entityReader.scanName(fastchar);
-            element.rawname = element.localpart;
-            return;
-        }
-        entityReader.scanQName(fastchar, element);
-        if (entityReader.lookingAtChar(':', false)) {
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                       XMLMessages.XML_DOMAIN,
-                                       XMLMessages.MSG_TWO_COLONS_IN_QNAME,
-                                       XMLMessages.P5_INVALID_CHARACTER,
-                                       null,
-                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            entityReader.skipPastNmtoken(' ');
-        }
-
-    } // scanElementType(XMLEntityHandler.EntityReader,char,QName)
-
-    public void checkForElementTypeWithPEReference(XMLEntityHandler.EntityReader entityReader, 
-                                                   char fastchar, QName element) throws Exception {
-
-        if (!fNamespacesEnabled) {
-            element.clear();
-            element.localpart = entityReader.scanName(fastchar);
-            element.rawname = element.localpart;
-            return;
-        }
-        entityReader.scanQName(fastchar, element);
-        if (entityReader.lookingAtChar(':', false)) {
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                       XMLMessages.XML_DOMAIN,
-                                       XMLMessages.MSG_TWO_COLONS_IN_QNAME,
-                                       XMLMessages.P5_INVALID_CHARACTER,
-                                       null,
-                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            entityReader.skipPastNmtoken(' ');
-        }
-
-    } // checkForElementTypeWithPEReference(XMLEntityHandler.EntityReader,char,QName)
-
-    public void checkForAttributeNameWithPEReference(XMLEntityHandler.EntityReader entityReader, 
-                                                     char fastchar, QName attribute) throws Exception {
-
-        if (!fNamespacesEnabled) {
-            attribute.clear();
-            attribute.localpart = entityReader.scanName(fastchar);
-            attribute.rawname = attribute.localpart;
-            return;
-        }
-
-        entityReader.scanQName(fastchar, attribute);
-        if (entityReader.lookingAtChar(':', false)) {
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                       XMLMessages.XML_DOMAIN,
-                                       XMLMessages.MSG_TWO_COLONS_IN_QNAME,
-                                       XMLMessages.P5_INVALID_CHARACTER,
-                                       null,
-                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            entityReader.skipPastNmtoken(' ');
-        }
-
-    } // checkForAttributeNameWithPEReference(XMLEntityHandler.EntityReader,char,QName)
-
-    public int checkForNameWithPEReference(XMLEntityHandler.EntityReader entityReader, char fastcheck) throws Exception {
-        //
-        // REVISIT - what does this have to do with PE references?
-        //
-        int valueIndex = entityReader.scanName(fastcheck);
-        return valueIndex;
-    }
-
-    public int checkForNmtokenWithPEReference(XMLEntityHandler.EntityReader entityReader, char fastcheck) throws Exception {
-        //
-        // REVISIT - what does this have to do with PE references?
-        //
-        int nameOffset = entityReader.currentOffset();
-        entityReader.skipPastNmtoken(fastcheck);
-        int nameLength = entityReader.currentOffset() - nameOffset;
-        if (nameLength == 0)
-            return -1;
-        int valueIndex = entityReader.addSymbol(nameOffset, nameLength);
-        return valueIndex;
-    }
-
-    public int scanDefaultAttValue(QName element, QName attribute, 
-                                   int attType, int enumeration) throws Exception {
-        /***/
-        if (fValidationEnabled && attType == XMLAttributeDecl.TYPE_ID) {
-            reportRecoverableXMLError(XMLMessages.MSG_ID_DEFAULT_TYPE_INVALID,
-                                      XMLMessages.VC_ID_ATTRIBUTE_DEFAULT,
-                                      fStringPool.toString(attribute.rawname));
-        }
-        /***/
-        int defaultAttValue = scanDefaultAttValue(element, attribute);
-        if (defaultAttValue == -1)
-            return -1;
-        // REVISIT
-        /***
-        if (attType != fCDATASymbol) {
-            // REVISIT: Validation. Should we pass in the element or is this
-            //          default attribute value normalization?
-            defaultAttValue = fValidator.normalizeAttValue(null, attribute, defaultAttValue, attType, enumeration);
-        }
-        /***/
-        return defaultAttValue;
-    }
-
-    public int normalizeDefaultAttValue( QName attribute, int defaultAttValue, 
-                                         int attType, int enumeration, 
-                                         boolean list) throws Exception {
-            //
-            // Normalize attribute based upon attribute type...
-            //
-            String attValue = fStringPool.toString(defaultAttValue);
-
-            if (list) {
-                StringTokenizer tokenizer = new StringTokenizer(attValue);
-                StringBuffer sb = new StringBuffer(attValue.length());
-                boolean ok = true;
-                if (tokenizer.hasMoreTokens()) {
-                    while (true) {
-                        String nmtoken = tokenizer.nextToken();
-                        if (attType == XMLAttributeDecl.TYPE_NMTOKEN) {
-                            if (fValidationEnabled && !XMLCharacterProperties.validNmtoken(nmtoken)) {
-                                ok = false;
-                            }
-                        }
-                        else if (attType == XMLAttributeDecl.TYPE_IDREF || attType == XMLAttributeDecl.TYPE_ENTITY) {
-                            if (fValidationEnabled && !XMLCharacterProperties.validName(nmtoken)) {
-                                ok = false;
-                            }
-                            // REVISIT: a Hack!!! THis is to pass SUN test /invalid/attr11.xml and attr12.xml
-                            // not consistent with XML1.0 spec VC: Attribute Default Legal
-                            if (fValidationEnabled && attType == XMLAttributeDecl.TYPE_ENTITY)
-                            if (! ((DefaultEntityHandler) fEntityHandler).isUnparsedEntity(defaultAttValue)) {
-                                reportRecoverableXMLError(XMLMessages.MSG_ENTITY_INVALID,
-                                                          XMLMessages.VC_ENTITY_NAME,
-                                                          fStringPool.toString(attribute.rawname), nmtoken);
-                            }
-
-                        }
-                        sb.append(nmtoken);
-                        if (!tokenizer.hasMoreTokens()) {
-                            break;
-                        }
-                        sb.append(' ');
-                    }
-                }
-                String newAttValue = sb.toString();
-                if (fValidationEnabled && (!ok || newAttValue.length() == 0)) {
-                    reportRecoverableXMLError(XMLMessages.MSG_ATT_DEFAULT_INVALID,
-                                              XMLMessages.VC_ATTRIBUTE_DEFAULT_LEGAL,
-                                              fStringPool.toString(attribute.rawname), newAttValue);
-                }
-                if (!newAttValue.equals(attValue)) {
-                    defaultAttValue = fStringPool.addString(newAttValue);
-                }
-                return defaultAttValue;
-            }
-            else {
-                String newAttValue = attValue.trim();
-
-                if (fValidationEnabled) {
-                    // REVISIT - can we release the old string?
-                    if (newAttValue != attValue) {
-                       defaultAttValue = fStringPool.addSymbol(newAttValue);
-                    } 
-                    else {
-                       defaultAttValue = fStringPool.addSymbol(defaultAttValue);
-                    }
-                    if (attType == XMLAttributeDecl.TYPE_ENTITY ||
-                        attType == XMLAttributeDecl.TYPE_ID ||
-                        attType == XMLAttributeDecl.TYPE_IDREF ||
-                        attType == XMLAttributeDecl.TYPE_NOTATION)  {
-
-                        // REVISIT: A Hack!!! THis is to pass SUN test /invalid/attr11.xml and attr12.xml
-                        // not consistent with XML1.0 spec VC: Attribute Default Legal
-                        if (attType == XMLAttributeDecl.TYPE_ENTITY)
-                        if (! ((DefaultEntityHandler) fEntityHandler).isUnparsedEntity(defaultAttValue)) {
-                            reportRecoverableXMLError(XMLMessages.MSG_ENTITY_INVALID,
-                                                      XMLMessages.VC_ENTITY_NAME,
-                                                      fStringPool.toString(attribute.rawname), newAttValue);
-                        }
-                        
-                        if (!XMLCharacterProperties.validName(newAttValue)) {
-                            reportRecoverableXMLError(XMLMessages.MSG_ATT_DEFAULT_INVALID,
-                                                      XMLMessages.VC_ATTRIBUTE_DEFAULT_LEGAL,
-                                                      fStringPool.toString(attribute.rawname), newAttValue);
-                        }
-
-                    }
-                    else if (attType == XMLAttributeDecl.TYPE_NMTOKEN ||
-                             attType == XMLAttributeDecl.TYPE_ENUMERATION ) {
-
-                        if (!XMLCharacterProperties.validNmtoken(newAttValue)) {
-                            reportRecoverableXMLError(XMLMessages.MSG_ATT_DEFAULT_INVALID,
-                                                      XMLMessages.VC_ATTRIBUTE_DEFAULT_LEGAL,
-                                                      fStringPool.toString(attribute.rawname), newAttValue);
-                        }
-                    }
-                    
-                    if (attType == XMLAttributeDecl.TYPE_NOTATION ||
-                        attType == XMLAttributeDecl.TYPE_ENUMERATION ) {
-
-                        if ( !fStringPool.stringInList(enumeration, defaultAttValue) ) {
-                            reportRecoverableXMLError(XMLMessages.MSG_ATT_DEFAULT_INVALID,
-                                                      XMLMessages.VC_ATTRIBUTE_DEFAULT_LEGAL,
-                                                      fStringPool.toString(attribute.rawname), newAttValue);
-                        }
-                    }
-
-                } 
-                else if (newAttValue != attValue) {
-                    // REVISIT - can we release the old string?
-                    defaultAttValue = fStringPool.addSymbol(newAttValue);
-                }
-            }
-
-            return defaultAttValue;
-    }
-    /***
-    public boolean scanDoctypeDecl(boolean standalone) throws Exception {
-        fStandaloneReader = standalone ? fEntityHandler.getReaderId() : -1;
-        fDeclsAreExternal = false;
-        if (!fDTDScanner.scanDoctypeDecl()) {
-            return false;
-        }
-        if (fDTDScanner.getReadingExternalEntity()) {
-            fDTDScanner.scanDecls(true);
-        }
-        fDTDHandler.endDTD();
-        return true;
-    }
-    /***/
-
-} // class XMLDTDScanner
diff --git a/src/org/apache/xerces/framework/XMLDocumentHandler.java b/src/org/apache/xerces/framework/XMLDocumentHandler.java
deleted file mode 100644
index b4dafcc..0000000
--- a/src/org/apache/xerces/framework/XMLDocumentHandler.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.framework;
-
-import org.apache.xerces.utils.QName;
-
-/**
- * XMLValidator defines the interface that XMLDocumentScanner and XML
- * EntityHandler have with an object that serves as a pluggable validator.
- * This abstraction allows validators for XML grammar languages to be
- * plugged in and queried for validity checks as the scanner processes
- * a document.
- * <p>
- * The document scanner and entity handler need to ask the validator object
- * for this information because the validator object is responsible for reading
- * the grammar specification file (which contains markup declarations and entity
- * declarations)
- *
- * @version $Id$
- */
-
-public interface XMLDocumentHandler {
-
-    /**
-     * Callback for start of document
-     *
-     * If the there is no version info, encoding info, or standalone info,
-     * the corresponding argument will be set to -1.
-     *
-     * @exception java.lang.Exception
-     */
-    public void startDocument()  throws Exception;
-
-    /**
-     * callback for the end of document.
-     *
-     * @exception java.lang.Exception
-     */
-    public void endDocument() throws Exception;
-
-    /**
-     * Signal the XML declaration of a document
-     *
-     * @param version the handle in the string pool for the version number
-     * @param encoding the handle in the string pool for the encoding
-     * @param standalong the handle in the string pool for the standalone value
-     * @exception java.lang.Exception
-     */
-    public void xmlDecl(int version, int encoding, int standalone) throws Exception;
-
-    /**
-     * Signal the Text declaration of an external entity.
-     *
-     * @exception java.lang.Exception
-     */
-    public void textDecl(int version, int encoding) throws Exception;
-
-    /**
-     * callback for the start of a namespace declaration scope.
-     *
-     * @param prefix string pool index of the namespace prefix being declared
-     * @param uri string pool index of the namespace uri begin bound
-     * @param java.lang.Exception
-     */
-    public void startNamespaceDeclScope(int prefix, int uri) throws Exception;
-
-    /**
-     * callback for the end a namespace declaration scope.
-     *
-     * @param prefix string pool index of the namespace prefix being declared
-     * @exception java.lang.Exception
-     */
-    public void endNamespaceDeclScope(int prefix) throws Exception;
-
-    /**
-     * callback for the start of element.
-     *
-     * @param elementType element handle for the element being scanned
-     * @param attrList attrList containing the attributes of the element
-     * @param attrListHandle handle into attrList.  Allows attributes to be retreived.
-     * @exception java.lang.Exception
-     */
-    public void startElement(QName element, 
-                             XMLAttrList attrList, int attrListHandle) throws Exception;
-
-    /**
-     * callback for end of element.
-     *
-     * @param elementType element handle for the element being scanned
-     * @exception java.lang.Exception
-     */
-    public void endElement(QName element) throws Exception;
-
-    /**
-     * callback for start of entity reference.
-     *
-     * @param entityName string pool index of the entity name
-     * @param entityType the XMLEntityHandler.ENTITYTYPE_* type
-     * @see org.apache.xerces.readers.XMLEntityHandler
-     * @param entityContext the XMLEntityHandler.ENTITYREF_* type for where
-     *        the entity reference appears
-     * @see org.apache.xerces.readers.XMLEntityHandler
-     * @exception java.lang.Exception
-     */
-    public void startEntityReference(int entityName, int entityType, int entityContext) throws Exception;
-
-    /**
-     * callback for end of entity reference.
-     *
-     * @param entityName string pool index of the entity anem
-     * @param entityType the XMLEntityHandler.ENTITYTYPE_* type
-     * @see org.apache.xerces.readers.XMLEntityHandler
-     * @param entityContext the XMLEntityHandler.ENTITYREF_* type for where
-     *        the entity reference appears
-     * @see org.apache.xerces.readers.XMLEntityHandler
-     * @exception java.lang.Exception
-     */
-    public void endEntityReference(int entityName, int entityType, int entityContext) throws Exception;
-
-    /**
-     * callback for processing instruction.
-     *
-     * @param target string pool index of the PI target
-     * @param data string pool index of the PI data
-     * @exception java.lang.Exception
-     */
-    public void processingInstruction(int target, int data) throws Exception;
-
-    /**
-     * callback for comment.
-     *
-     * @param comment string pool index of the comment text
-     * @exception java.lang.Exception
-     */
-    public void comment(int comment) throws Exception;
-
-    /**
-     * callback for characters (string pool form).
-     *
-     * @param data string pool index of the characters that were scanned
-     * @exception java.lang.Exception
-     */
-    public void characters(int data) throws Exception;
-
-    /**
-     * callback for characters.
-     *
-     * @param ch character array containing the characters that were scanned
-     * @param start offset in ch where scanned characters begin
-     * @param length length of scanned characters in ch
-     * @exception java.lang.Exception
-     */
-    public void characters(char ch[], int start, int length) throws Exception;
-
-    /**
-     * callback for ignorable whitespace.
-     *
-     * @param data string pool index of ignorable whitespace
-     * @exception java.lang.Exception
-     */
-    public void ignorableWhitespace(int data) throws Exception;
-
-    /**
-     * callback for ignorable whitespace.
-     *
-     * @param ch character array containing the whitespace that was scanned
-     * @param start offset in ch where scanned whitespace begins
-     * @param length length of scanned whitespace in ch
-     * @exception java.lang.Exception
-     */
-    public void ignorableWhitespace(char ch[], int start, int length) throws Exception;
-
-    /**
-     * callback for start of CDATA section.
-     * this callback marks the start of a CDATA section
-     *
-     * @exception java.lang.Exception
-     */
-    public void startCDATA() throws Exception;
-
-    /**
-     * callback for end of CDATA section.
-     * this callback marks the end of a CDATA section
-     *
-     * @exception java.lang.Exception
-     */
-    public void endCDATA() throws Exception;
-
-    //
-    // Additional DTD specific events.
-    //
-    public interface DTDHandler {
-        /**
-         * callback for the start of the DTD
-         * This function will be called when a &lt;!DOCTYPE...&gt; declaration is
-         * encountered.
-         *
-         * @param rootElementType element handle for the root element of the document
-         * @param publicId string pool index of the DTD's public ID
-         * @param systemId string pool index of the DTD's system ID
-         * @exception java.lang.Exception
-         */
-        public void startDTD(QName rootElement, int publicId, int systemId) throws Exception;
-
-        /**
-         * Supports DOM Level 2 internalSubset additions.
-         * Called when the internal subset is completely scanned.
-         */
-        public void internalSubset(int internalSubset) throws Exception;
-
-        /**
-         * Signal the Text declaration of an external entity.
-         *
-         * @exception java.lang.Exception
-         */
-        public void textDecl(int version, int encoding) throws Exception;
-
-        /**
-         * callback for the end of the DTD
-         * This function will be called at the end of the DTD. 
-         */
-        public void endDTD() throws Exception;
-
-        /**
-         * callback for an element declaration. 
-         *
-         * @param elementType element handle of the element being declared
-         * @param contentSpec contentSpec for the element being declared
-         * @see org.apache.xerces.framework.XMLContentSpec
-         * @exception java.lang.Exception
-         */
-        public void elementDecl(QName elementDecl, 
-                                int contentSpecType, 
-                                int contentSpecIndex,
-                                XMLContentSpec.Provider contentSpecProvider) throws Exception;
-
-        /**
-         * callback for an attribute list declaration. 
-         *
-         * @param elementType element handle for the attribute's element
-         * @param attrName string pool index of the attribute name
-         * @param attType type of attribute
-         * @param enumString String representing the values of the enumeration,
-         *        if the attribute is of enumerated type, or null if it is not.
-         * @param attDefaultType an integer value denoting the DefaultDecl value
-         * @param attDefaultValue string pool index of this attribute's default value 
-         *        or -1 if there is no defaultvalue 
-         * @exception java.lang.Exception
-         */
-        public void attlistDecl(QName elementDecl, QName attributeDecl,
-                                int attType, boolean attList,
-                                String enumString,
-                                int attDefaultType,
-                                int attDefaultValue) throws Exception;
-
-        /**
-         * callback for an internal parameter entity declaration.
-         *
-         * @param entityName string pool index of the entity name
-         * @param entityValue string pool index of the entity replacement text
-         * @exception java.lang.Exception
-         */
-        public void internalPEDecl(int entityName, int entityValue) throws Exception;
-
-        /**
-         * callback for an external parameter entity declaration. 
-         *
-         * @param entityName string pool index of the entity name
-         * @param publicId string pool index of the entity's public id.
-         * @param systemId string pool index of the entity's system id.
-         * @exception java.lang.Exception
-         */
-        public void externalPEDecl(int entityName, int publicId, int systemId) throws Exception;
-
-        /**
-         * callback for internal general entity declaration. 
-         *
-         * @param entityName string pool index of the entity name
-         * @param entityValue string pool index of the entity replacement text
-         * @exception java.lang.Exception
-         */
-        public void internalEntityDecl(int entityName, int entityValue) throws Exception;
-
-        /**
-         * callback for external general entity declaration. 
-         *
-         * @param entityName string pool index of the entity name
-         * @param publicId string pool index of the entity's public id.
-         * @param systemId string pool index of the entity's system id.
-         * @exception java.lang.Exception
-         */
-        public void externalEntityDecl(int entityName, int publicId, int systemId) throws Exception;
-
-        /**
-         * callback for an unparsed entity declaration. 
-         *
-         * @param entityName string pool index of the entity name
-         * @param publicId string pool index of the entity's public id.
-         * @param systemId string pool index of the entity's system id.
-         * @param notationName string pool index of the notation name.
-         * @exception java.lang.Exception
-         */
-        public void unparsedEntityDecl(int entityName, int publicId, int systemId, int notationName) throws Exception;
-
-        /**
-         * callback for a notation declaration.
-         *
-         * @param notationName string pool index of the notation name
-         * @param publicId string pool index of the notation's public id.
-         * @param systemId string pool index of the notation's system id.
-         * @exception java.lang.Exception
-         */
-        public void notationDecl(int notationName, int publicId, int systemId) throws Exception;
-
-        /**
-         * Callback for processing instruction in DTD.  
-         *
-         * @param target the string pool index of the PI's target
-         * @param data the string pool index of the PI's data
-         * @exception java.lang.Exception
-         */
-        public void processingInstruction(int targetIndex, int dataIndex) throws Exception;
-
-        /**
-         * Callback for comment in DTD.
-         * 
-         * @param comment the string pool index of the comment text
-         * @exception java.lang.Exception
-         */
-        public void comment(int dataIndex) throws Exception;
-    }
-}
diff --git a/src/org/apache/xerces/framework/XMLDocumentScanner.java b/src/org/apache/xerces/framework/XMLDocumentScanner.java
deleted file mode 100644
index 6c98131..0000000
--- a/src/org/apache/xerces/framework/XMLDocumentScanner.java
+++ /dev/null
@@ -1,2279 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.framework;
-
-import org.apache.xerces.readers.XMLEntityHandler;
-import org.apache.xerces.readers.DefaultEntityHandler;
-import org.apache.xerces.utils.ChunkyCharArray;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.utils.XMLCharacterProperties;
-import org.apache.xerces.utils.XMLMessages;
-import org.apache.xerces.validators.common.GrammarResolver;
-
-import org.xml.sax.Locator;
-import org.xml.sax.SAXParseException;
-
-/**
- * This class recognizes most of the grammer for an XML processor.
- * Additional support is provided by the XMLEntityHandler, via the
- * XMLEntityReader instances it creates, which are used to process
- * simple constructs like string literals and character data between
- * markup.  The XMLDTDScanner class contains the remaining support
- * for the grammer of DTD declarations.  When a &lt;!DOCTYPE ...&gt; is
- * found in the document, the scanDoctypeDecl method will then be
- * called and the XMLDocumentScanner subclass is responsible for
- * "connecting" that method to the corresponding method provided
- * by the XMLDTDScanner class.
- *
- * @version $Id$
- */
-public final class XMLDocumentScanner {
-    //
-    // Constants
-    //
-
-    //
-    // These character arrays are used as parameters for calls to the
-    // XMLEntityHandler.EntityReader skippedString() method.  Some have
-    // package access for use by the inner dispatcher classes.
-    //
-
-    //
-    // [19] CDStart ::= '<![CDATA['
-    //
-    static final char[] cdata_string = { '[','C','D','A','T','A','[' };
-    //
-    // [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
-    // [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
-    //
-    static final char[] xml_string = { 'x','m','l' };
-    //
-    // [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
-    //
-    private static final char[] version_string = { 'v','e','r','s','i','o','n' };
-    //
-    // [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
-    //                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
-    //
-    static final char[] doctype_string = { 'D','O','C','T','Y','P','E' };
-    //
-    // [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'")
-    //                 | ('"' ('yes' | 'no') '"'))
-    //
-    private static final char[] standalone_string = { 's','t','a','n','d','a','l','o','n','e' };
-    //
-    // [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'" )
-    //
-    private static final char[] encoding_string = { 'e','n','c','o','d','i','n','g' };
-
-    /*
-     * Return values for the EventHandler scanAttValue method.
-     */
-    public static final int
-        RESULT_SUCCESS          =  0,
-        RESULT_FAILURE          = -1,
-        RESULT_DUPLICATE_ATTR   = -2;
-
-    /** Scanner states */
-    static final int
-        SCANNER_STATE_XML_DECL                  =  0,
-        SCANNER_STATE_START_OF_MARKUP           =  1,
-        SCANNER_STATE_COMMENT                   =  2,
-        SCANNER_STATE_PI                        =  3,
-        SCANNER_STATE_DOCTYPE                   =  4,
-        SCANNER_STATE_PROLOG                    =  5,
-        SCANNER_STATE_ROOT_ELEMENT              =  6,
-        SCANNER_STATE_CONTENT                   =  7,
-        SCANNER_STATE_REFERENCE                 =  8,
-        SCANNER_STATE_ATTRIBUTE_LIST            =  9,
-        SCANNER_STATE_ATTRIBUTE_NAME            = 10,
-        SCANNER_STATE_ATTRIBUTE_VALUE           = 11,
-        SCANNER_STATE_TRAILING_MISC             = 12,
-        SCANNER_STATE_END_OF_INPUT              = 13,
-        SCANNER_STATE_TERMINATED                = 14;
-
-    //
-    // Instance Variables
-    //
-    /***/
-    // NOTE: Used by old implementation of scanElementType method. -Ac
-    private StringPool.CharArrayRange fCurrentElementCharArrayRange = null;
-    /***/
-    int fAttrListHandle = -1;
-    XMLAttrList fAttrList = null;
-    GrammarResolver fGrammarResolver = null;
-    XMLDTDScanner fDTDScanner = null;
-    boolean fNamespacesEnabled = false;
-    boolean fValidationEnabled = false;
-    QName fElementQName = new QName();
-    QName fAttributeQName = new QName();
-    QName fCurrentElementQName = new QName();
-    ScannerDispatcher fDispatcher = null;
-    EventHandler fEventHandler = null;
-    XMLDocumentHandler.DTDHandler fDTDHandler = null;
-    StringPool fStringPool = null;
-    XMLErrorReporter fErrorReporter = null;
-    XMLEntityHandler fEntityHandler = null;
-    XMLEntityHandler.EntityReader fEntityReader = null;
-    XMLEntityHandler.CharBuffer fLiteralData = null;
-    boolean fSeenRootElement = false;
-    boolean fSeenDoctypeDecl = false;
-    boolean fStandalone = false;
-    boolean fParseTextDecl = false;
-    boolean fScanningDTD = false;
-    int fScannerState = SCANNER_STATE_XML_DECL;
-    int fReaderId = -1;
-    int fAttValueReader = -1;
-    int fAttValueElementType = -1;
-    int fAttValueAttrName = -1;
-    int fAttValueOffset = -1;
-    int fAttValueMark = -1;
-    int fScannerMarkupDepth = 0;
-
-    //
-    // Interfaces
-    //
-
-    /**
-     * This interface must be implemented by the users of the XMLDocumentScanner class.
-     * These methods form the abstraction between the implementation semantics and the
-     * more generic task of scanning the XML non-DTD grammar.
-     */
-    public interface EventHandler {
-        /**
-         * Signal standalone = "yes"
-         *
-         * @exception java.lang.Exception
-         */
-        public void callStandaloneIsYes() throws Exception;
-
-        /**
-         * Signal the start of a document
-         *
-         * @exception java.lang.Exception
-         */
-        public void callStartDocument() throws Exception;
-        /**
-         * Signal the end of a document
-         *
-         * @exception java.lang.Exception
-         */
-        public void callEndDocument() throws Exception;
-        /**
-         * Signal the XML declaration of a document
-         *
-         * @param version the handle in the string pool for the version number
-         * @param encoding the handle in the string pool for the encoding
-         * @param standalong the handle in the string pool for the standalone value
-         * @exception java.lang.Exception
-         */
-        public void callXMLDecl(int version, int encoding, int standalone) throws Exception;
-        /**
-         * Signal the Text declaration of an external entity.
-         *
-         * @param version the handle in the string pool for the version number
-         * @param encoding the handle in the string pool for the encoding
-         * @exception java.lang.Exception
-         */
-        public void callTextDecl(int version, int encoding) throws Exception;
-        /**
-         * signal the scanning of a start element tag
-         * 
-         * @param element Element name scanned.
-         * @exception java.lang.Exception
-         */
-        public void callStartElement(QName element) throws Exception;
-        /**
-         * Signal the scanning of an element name in a start element tag.
-         *
-         * @param element Element name scanned.
-         */
-        public void element(QName element) throws Exception;
-        /**
-         * Signal the scanning of an attribute associated to the previous
-         * start element tag.
-         *
-         * @param element Element name scanned.
-         * @param attrName Attribute name scanned.
-         * @param attrValue The string pool index of the attribute value.
-         */
-        public boolean attribute(QName element, QName attrName, int attrValue) throws Exception;
-        /**
-         * signal the scanning of an end element tag
-         *
-         * @param readerId the Id of the reader being used to scan the end tag.
-         * @exception java.lang.Exception
-         */
-        public void callEndElement(int readerId) throws Exception;
-        /**
-         * Signal the start of a CDATA section
-         * @exception java.lang.Exception
-         */
-        public void callStartCDATA() throws Exception;
-        /**
-         * Signal the end of a CDATA section
-         * @exception java.lang.Exception
-         */
-        public void callEndCDATA() throws Exception;
-        /**
-         * Report the scanning of character data
-         *
-         * @param ch the handle in the string pool of the character data that was scanned
-         * @exception java.lang.Exception
-         */
-        public void callCharacters(int ch) throws Exception;
-        /**
-         * Report the scanning of a processing instruction
-         *
-         * @param piTarget the handle in the string pool of the processing instruction targe
-         * @param piData the handle in the string pool of the processing instruction data
-         * @exception java.lang.Exception
-         */
-        public void callProcessingInstruction(int piTarget, int piData) throws Exception;
-        /**
-         * Report the scanning of a comment
-         *
-         * @param data the handle in the string pool of the comment text
-         * @exception java.lang.Exception
-         */
-        public void callComment(int data) throws Exception;
-    }
-
-    /**
-     * Constructor
-     */
-    public XMLDocumentScanner(StringPool stringPool,
-                              XMLErrorReporter errorReporter,
-                              XMLEntityHandler entityHandler,
-                              XMLEntityHandler.CharBuffer literalData) {
-        fStringPool = stringPool;
-        fErrorReporter = errorReporter;
-        fEntityHandler = entityHandler;
-        fLiteralData = literalData;
-        fDispatcher = new XMLDeclDispatcher();
-        fAttrList = new XMLAttrList(fStringPool);
-    }
-
-    /**
-     * Set the event handler
-     *
-     * @param eventHandler The place to send our callbacks.
-     */
-    public void setEventHandler(XMLDocumentScanner.EventHandler eventHandler) {
-        fEventHandler = eventHandler;
-    }
-
-    /** Set the DTD handler. */
-    public void setDTDHandler(XMLDocumentHandler.DTDHandler dtdHandler) {
-        fDTDHandler = dtdHandler;
-    }
-
-    /** Sets the grammar resolver. */
-    public void setGrammarResolver(GrammarResolver resolver) {
-        fGrammarResolver = resolver;
-    }
-
-    /**
-     * reset the parser so that the instance can be reused
-     *
-     * @param stringPool the string pool instance to be used by the reset parser
-     */
-    public void reset(StringPool stringPool, XMLEntityHandler.CharBuffer literalData) {
-        fStringPool = stringPool;
-        fLiteralData = literalData;
-        fParseTextDecl = false;
-        fSeenRootElement = false;
-        fSeenDoctypeDecl = false;
-        fStandalone = false;
-        fScanningDTD = false;
-        fDispatcher = new XMLDeclDispatcher();
-        fScannerState = SCANNER_STATE_XML_DECL;
-        fScannerMarkupDepth = 0;
-        fAttrList = new XMLAttrList(fStringPool);
-    }
-
-    //
-    // From the standard:
-    //
-    // [1] document ::= prolog element Misc*
-    //
-    // [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
-    // [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
-    // [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
-    //
-    // The beginning of XMLDecl simplifies to:
-    //    '<?xml' S ...
-    //
-    // [27] Misc ::= Comment | PI |  S
-    // [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
-    // [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
-    // [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
-    //
-    // [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
-    //                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
-    //
-    /**
-     * Entry point for parsing
-     *
-     * @param doItAll if true the entire document is parsed otherwise just 
-     *                the next segment of the document is parsed
-     */
-    public boolean parseSome(boolean doItAll) throws Exception
-    {
-        do {
-            if (!fDispatcher.dispatch(doItAll))
-                return false;
-        } while (doItAll);
-        return true;
-    }
-
-    /**
-     * Change readers
-     *
-     * @param nextReader the new reader that the scanner will use
-     * @param nextReaderId id of the reader to change to
-     * @exception throws java.lang.Exception
-     */
-    public void readerChange(XMLEntityHandler.EntityReader nextReader, int nextReaderId) throws Exception {
-        fEntityReader = nextReader;
-        fReaderId = nextReaderId;
-        if (fScannerState == SCANNER_STATE_ATTRIBUTE_VALUE) {
-            fAttValueOffset = fEntityReader.currentOffset();
-            fAttValueMark = fAttValueOffset;
-        }
-
-        //also propagate the change to DTDScanner if there is one
-        if (fDTDScanner != null && fScanningDTD)
-            fDTDScanner.readerChange(nextReader, nextReaderId);
-    }
-
-    /**
-     * Handle the end of input
-     *
-     * @param entityName the handle in the string pool of the name of the entity which has reached end of input
-     * @param moreToFollow if true, there is still input left to process in other readers
-     * @exception java.lang.Exception
-     */
-    public void endOfInput(int entityName, boolean moreToFollow) throws Exception {
-        if (fDTDScanner != null && fScanningDTD){
-            fDTDScanner.endOfInput(entityName, moreToFollow);
-        }
-        fDispatcher.endOfInput(entityName, moreToFollow);
-    }
-
-    /** 
-     * Tell if scanner has reached end of input
-     * @return true if scanner has reached end of input.
-     */
-    public boolean atEndOfInput() {
-        return fScannerState == SCANNER_STATE_END_OF_INPUT;
-    }
-
-    //
-    // [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
-    //
-    /**
-     * Scan an attribute value
-     *
-     * @param elementType handle to the element whose attribute value is being scanned
-     * @param attrName handle in the string pool of the name of attribute being scanned
-     * @param asSymbol controls whether the value is a string (duplicates allowed) or a symbol (duplicates not allowed)
-     * @return handle in the string pool of the scanned value
-     * @exception java.lang.Exception
-     */
-    public int scanAttValue(QName element, QName attribute, boolean asSymbol) throws Exception {
-        boolean single;
-        if (!(single = fEntityReader.lookingAtChar('\'', true)) && !fEntityReader.lookingAtChar('\"', true)) {
-            reportFatalXMLError(XMLMessages.MSG_QUOTE_REQUIRED_IN_ATTVALUE,
-                                XMLMessages.P10_QUOTE_REQUIRED,
-                                element.rawname,
-                                attribute.rawname);
-            return -1;
-        }
-        char qchar = single ? '\'' : '\"';
-        fAttValueMark = fEntityReader.currentOffset();
-        int attValue = fEntityReader.scanAttValue(qchar, asSymbol);
-        if (attValue >= 0)
-            return attValue;
-        int previousState = setScannerState(SCANNER_STATE_ATTRIBUTE_VALUE);
-        fAttValueReader = fReaderId;
-        // REVISIT: What should this be?
-        fAttValueElementType = element.rawname;
-        // REVISIT: What should this be?
-        fAttValueAttrName = attribute.rawname;
-        fAttValueOffset = fEntityReader.currentOffset();
-        int dataOffset = fLiteralData.length();
-        if (fAttValueOffset - fAttValueMark > 0)
-            fEntityReader.append(fLiteralData, fAttValueMark, fAttValueOffset - fAttValueMark);
-        fAttValueMark = fAttValueOffset;
-        boolean setMark = false;
-        boolean skippedCR;
-        while (true) {
-            if (fEntityReader.lookingAtChar(qchar, true)) {
-                if (fReaderId == fAttValueReader)
-                    break;
-            } else if (fEntityReader.lookingAtChar(' ', true)) {
-                //
-                // no action required
-                //
-            } else if ((skippedCR = fEntityReader.lookingAtChar((char)0x0D, true)) || fEntityReader.lookingAtSpace(true)) {
-                if (fAttValueOffset - fAttValueMark > 0)
-                    fEntityReader.append(fLiteralData, fAttValueMark, fAttValueOffset - fAttValueMark);
-                setMark = true;
-                fLiteralData.append(' ');
-                if (skippedCR) {
-                    //
-                    // REVISIT - HACK !!!  code changed to pass incorrect OASIS test 'valid-sa-110'
-                    //  Uncomment the next line to conform to the spec...
-                    //
-                    //fEntityReader.lookingAtChar((char)0x0A, true);
-                }
-            } else if (fEntityReader.lookingAtChar('&', true)) {
-                if (fAttValueOffset - fAttValueMark > 0)
-                    fEntityReader.append(fLiteralData, fAttValueMark, fAttValueOffset - fAttValueMark);
-                setMark = true;
-                //
-                // Check for character reference first.
-                //
-                if (fEntityReader.lookingAtChar('#', true)) {
-                    int ch = scanCharRef();
-                    if (ch != -1) {
-                        if (ch < 0x10000)
-                            fLiteralData.append((char)ch);
-                        else {
-                            fLiteralData.append((char)(((ch-0x00010000)>>10)+0xd800));
-                            fLiteralData.append((char)(((ch-0x00010000)&0x3ff)+0xdc00));
-                        }
-                    }
-                } else {
-                    //
-                    // Entity reference
-                    //
-                    int nameOffset = fEntityReader.currentOffset();
-                    fEntityReader.skipPastName(';');
-                    int nameLength = fEntityReader.currentOffset() - nameOffset;
-                    if (nameLength == 0) {
-                        reportFatalXMLError(XMLMessages.MSG_NAME_REQUIRED_IN_REFERENCE,
-                                            XMLMessages.P68_NAME_REQUIRED);
-                    } else if (!fEntityReader.lookingAtChar(';', true)) {
-                        reportFatalXMLError(XMLMessages.MSG_SEMICOLON_REQUIRED_IN_REFERENCE,
-                                            XMLMessages.P68_SEMICOLON_REQUIRED,
-                                            fEntityReader.addString(nameOffset, nameLength));
-                    } else {
-                        int entityName = fEntityReader.addSymbol(nameOffset, nameLength);
-                        fEntityHandler.startReadingFromEntity(entityName, fScannerMarkupDepth, XMLEntityHandler.ENTITYREF_IN_ATTVALUE);
-                    }
-                }
-            } else if (fEntityReader.lookingAtChar('<', true)) {
-                if (fAttValueOffset - fAttValueMark > 0)
-                    fEntityReader.append(fLiteralData, fAttValueMark, fAttValueOffset - fAttValueMark);
-                setMark = true;
-                reportFatalXMLError(XMLMessages.MSG_LESSTHAN_IN_ATTVALUE,
-                                    XMLMessages.WFC_NO_LESSTHAN_IN_ATTVALUE,
-                                    element.rawname,
-                                    attribute.rawname);
-            } else if (!fEntityReader.lookingAtValidChar(true)) {
-                if (fAttValueOffset - fAttValueMark > 0)
-                    fEntityReader.append(fLiteralData, fAttValueMark, fAttValueOffset - fAttValueMark);
-                setMark = true;
-                int invChar = fEntityReader.scanInvalidChar();
-                if (fScannerState == SCANNER_STATE_END_OF_INPUT)
-                    return -1;
-                if (invChar >= 0) {
-                    reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_ATTVALUE,
-                                        XMLMessages.P10_INVALID_CHARACTER,
-                                        fStringPool.toString(element.rawname),
-                                        fStringPool.toString(attribute.rawname),
-                                        Integer.toHexString(invChar));
-                }
-            }
-            fAttValueOffset = fEntityReader.currentOffset();
-            if (setMark) {
-                fAttValueMark = fAttValueOffset;
-                setMark = false;
-            }
-        }
-        restoreScannerState(previousState);
-        int dataLength = fLiteralData.length() - dataOffset;
-        if (dataLength == 0) {
-            return fEntityReader.addString(fAttValueMark, fAttValueOffset - fAttValueMark);
-        }
-        if (fAttValueOffset - fAttValueMark > 0) {
-            fEntityReader.append(fLiteralData, fAttValueMark, fAttValueOffset - fAttValueMark);
-            dataLength = fLiteralData.length() - dataOffset;
-        }
-        int value = fLiteralData.addString(dataOffset, dataLength);
-        return value;
-    }
-
-    /**
-     * Check the value of an XML Language attribute
-     * @param langValue the handle in the string pool of the value to be checked
-     * @exception java.lang.Exception
-     */
-    public void checkXMLLangAttributeValue(int langValue) throws Exception {
-        String lang = fStringPool.toString(langValue);
-        int offset = -1;
-        if (lang.length() >= 2) {
-            char ch0 = lang.charAt(0);
-            if (lang.charAt(1) == '-') {
-                if (ch0 == 'i' || ch0 == 'I' || ch0 == 'x' || ch0 == 'X') {
-                    offset = 1;
-                }
-            } else {
-                char ch1 = lang.charAt(1);
-                if (((ch0 >= 'a' && ch0 <= 'z') || (ch0 >= 'A' && ch0 <= 'Z')) &&
-                    ((ch1 >= 'a' && ch1 <= 'z') || (ch1 >= 'A' && ch1 <= 'Z'))) {
-                        offset = 2;
-                }
-            }
-        }
-        if (offset > 0 && lang.length() > offset) {
-            char ch = lang.charAt(offset++);
-            if (ch != '-') {
-                offset = -1;
-            } else {
-                while (true) {
-                    if (ch == '-') {
-                        if (lang.length() == offset) {
-                            offset = -1;
-                            break;
-                        }
-                        ch = lang.charAt(offset++);
-                        if ((ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z')) {
-                            offset = -1;
-                            break;
-                        }
-                        if (lang.length() == offset)
-                            break;
-                    } else if ((ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z')) {
-                        offset = -1;
-                        break;
-                    } else if (lang.length() == offset)
-                        break;
-                    ch = lang.charAt(offset++);
-                }
-            }
-        }
-        if (offset == -1) {
-            reportFatalXMLError(XMLMessages.MSG_XML_LANG_INVALID,
-                                XMLMessages.P33_INVALID,
-                                lang);
-        }
-    }
-
-    //
-    //
-    //
-    void reportFatalXMLError(int majorCode, int minorCode) throws Exception {
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   null,
-                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-    }
-    void reportFatalXMLError(int majorCode, int minorCode, int stringIndex1) throws Exception {
-        Object[] args = { fStringPool.toString(stringIndex1) };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-    }
-    void reportFatalXMLError(int majorCode, int minorCode, String string1) throws Exception {
-        Object[] args = { string1 };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-    }
-    void reportFatalXMLError(int majorCode, int minorCode, int stringIndex1, int stringIndex2) throws Exception {
-        Object[] args = { fStringPool.toString(stringIndex1),
-                          fStringPool.toString(stringIndex2) };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-    }
-    void reportFatalXMLError(int majorCode, int minorCode, String string1, String string2) throws Exception {
-        Object[] args = { string1, string2 };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-    }
-    void reportFatalXMLError(int majorCode, int minorCode, String string1, String string2, String string3) throws Exception {
-        Object[] args = { string1, string2, string3 };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-    }
-    void abortMarkup(int majorCode, int minorCode) throws Exception {
-        reportFatalXMLError(majorCode, minorCode);
-        skipPastEndOfCurrentMarkup();
-    }
-    void abortMarkup(int majorCode, int minorCode, int stringIndex1) throws Exception {
-        reportFatalXMLError(majorCode, minorCode, stringIndex1);
-        skipPastEndOfCurrentMarkup();
-    }
-    void abortMarkup(int majorCode, int minorCode, String string1) throws Exception {
-        reportFatalXMLError(majorCode, minorCode, string1);
-        skipPastEndOfCurrentMarkup();
-    }
-    void abortMarkup(int majorCode, int minorCode, int stringIndex1, int stringIndex2) throws Exception {
-        reportFatalXMLError(majorCode, minorCode, stringIndex1, stringIndex2);
-        skipPastEndOfCurrentMarkup();
-    }
-    void skipPastEndOfCurrentMarkup() throws Exception {
-        fEntityReader.skipToChar('>');
-        if (fEntityReader.lookingAtChar('>', true))
-            fScannerMarkupDepth--;
-    }
-    //
-    //
-    //
-    int setScannerState(int state) {
-        int oldState = fScannerState;
-        fScannerState = state;
-        return oldState;
-    }
-    void restoreScannerState(int state) {
-        if (fScannerState != SCANNER_STATE_END_OF_INPUT)
-            fScannerState = state;
-    }
-    //
-    //
-    //
-    /**
-     * The main loop of the scanner is implemented by calling the dispatch method
-     * of ScannerDispatcher with a flag which tells the dispatcher whether to continue
-     * or return.  The scanner logic is split up into dispatchers for various syntatic
-     * components of XML.  //REVISIT more rationale needed
-     */
-    interface ScannerDispatcher {
-        /**
-         * scan an XML syntactic component 
-         *
-         * @param keepgoing if true continue on to the next dispatcher, otherwise return
-         * @return true if scanning was successful //REVISIT - does it ever return false or does it just throw?
-         * @exception java.lang.Exception
-         */
-        boolean dispatch(boolean keepgoing) throws Exception;
-        /**
-         * endOfInput encapsulates the end of entity handling for each dispatcher 
-         *
-         * @param entityName StringPool handle of the entity that has reached the end
-         * @param moreToFollow true if there is more input to be read
-         * @exception
-         */
-        void endOfInput(int entityName, boolean moreToFollow) throws Exception;
-    }
-    final class XMLDeclDispatcher implements ScannerDispatcher {
-        public boolean dispatch(boolean keepgoing) throws Exception {
-            fEventHandler.callStartDocument();
-            if (fEntityReader.lookingAtChar('<', true)) {
-                fScannerMarkupDepth++;
-                setScannerState(SCANNER_STATE_START_OF_MARKUP);
-                if (fEntityReader.lookingAtChar('?', true)) {
-                    int piTarget = fEntityReader.scanName(' ');
-                    if (piTarget == -1) {
-                        abortMarkup(XMLMessages.MSG_PITARGET_REQUIRED,
-                                    XMLMessages.P16_PITARGET_REQUIRED);
-                    } else if ("xml".equals(fStringPool.toString(piTarget))) {
-                        if (fEntityReader.lookingAtSpace(true)) { // an XMLDecl looks like a PI with the target 'xml'
-                            scanXMLDeclOrTextDecl(false);
-                        } else { // a PI target matching 'xml'
-                            abortMarkup(XMLMessages.MSG_RESERVED_PITARGET,
-                                        XMLMessages.P17_RESERVED_PITARGET);
-                        }
-                    } else { // PI
-                      scanPI(piTarget);
-                    }
-                    fDispatcher = new PrologDispatcher();
-                    restoreScannerState(SCANNER_STATE_PROLOG);
-                    return true;
-                }
-                if (fEntityReader.lookingAtChar('!', true)) {
-                    if (fEntityReader.lookingAtChar('-', true)) { // comment ?
-                        if (fEntityReader.lookingAtChar('-', true)) {
-                            scanComment(); // scan through the closing '-->'
-                        } else {
-                            abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_PROLOG,
-                                        XMLMessages.P22_NOT_RECOGNIZED);
-                        }
-                    } else {
-                        if (fEntityReader.skippedString(doctype_string)) {
-                            setScannerState(SCANNER_STATE_DOCTYPE);
-                            fSeenDoctypeDecl = true;
-                            scanDoctypeDecl(fStandalone); // scan through the closing '>'
-                            fScannerMarkupDepth--;
-                            fDispatcher = new PrologDispatcher();
-                            restoreScannerState(SCANNER_STATE_PROLOG);
-                            return true;
-                        } else {
-                            abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_PROLOG,
-                                        XMLMessages.P22_NOT_RECOGNIZED);
-                        }
-                    }
-                } else {
-                    fDispatcher = new ContentDispatcher();
-                    restoreScannerState(SCANNER_STATE_ROOT_ELEMENT);
-                    return true;
-                }
-            } else {
-                if (fEntityReader.lookingAtSpace(true)) {
-                    fEntityReader.skipPastSpaces();
-                } else if (!fEntityReader.lookingAtValidChar(false)) {
-                    int invChar = fEntityReader.scanInvalidChar();
-                    if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                        if (invChar >= 0) {
-                            String arg = Integer.toHexString(invChar);
-                            reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_PROLOG,
-                                                XMLMessages.P22_INVALID_CHARACTER,
-                                                arg);
-                        }
-                    }
-                } else {
-                    reportFatalXMLError(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_PROLOG,
-                                        XMLMessages.P22_NOT_RECOGNIZED);
-                    fEntityReader.lookingAtValidChar(true);
-                }
-            }
-            fDispatcher = new PrologDispatcher();
-            restoreScannerState(SCANNER_STATE_PROLOG);
-            return true;
-        }
-        public void endOfInput(int entityName, boolean moreToFollow) throws Exception {
-            switch (fScannerState) {
-            case SCANNER_STATE_XML_DECL:
-            case SCANNER_STATE_START_OF_MARKUP:
-            case SCANNER_STATE_DOCTYPE:
-                break;
-            case SCANNER_STATE_COMMENT:
-                if (!moreToFollow) {
-                    reportFatalXMLError(XMLMessages.MSG_COMMENT_UNTERMINATED,
-                                        XMLMessages.P15_UNTERMINATED);
-                } else {
-                    reportFatalXMLError(XMLMessages.MSG_COMMENT_NOT_IN_ONE_ENTITY,
-                                        XMLMessages.P78_NOT_WELLFORMED);
-                }
-                break;
-            case SCANNER_STATE_PI:
-                if (!moreToFollow) {
-                    reportFatalXMLError(XMLMessages.MSG_PI_UNTERMINATED,
-                                        XMLMessages.P16_UNTERMINATED);
-                } else {
-                    reportFatalXMLError(XMLMessages.MSG_PI_NOT_IN_ONE_ENTITY,
-                                        XMLMessages.P78_NOT_WELLFORMED);
-                }
-                break;
-            default:
-                throw new RuntimeException("FWK001 1] ScannerState="+fScannerState+"\n" + "1\t"+fScannerState);
-            }
-            if (!moreToFollow) {
-                reportFatalXMLError(XMLMessages.MSG_ROOT_ELEMENT_REQUIRED,
-                                    XMLMessages.P1_ELEMENT_REQUIRED);
-                fDispatcher = new EndOfInputDispatcher();
-                setScannerState(SCANNER_STATE_END_OF_INPUT);
-            }
-        }
-    }
-    final class PrologDispatcher implements ScannerDispatcher {
-        public boolean dispatch(boolean keepgoing) throws Exception {
-            do {
-                if (fEntityReader.lookingAtChar('<', true)) {
-                    fScannerMarkupDepth++;
-                    setScannerState(SCANNER_STATE_START_OF_MARKUP);
-                    if (fEntityReader.lookingAtChar('?', true)) {
-                        int piTarget = fEntityReader.scanName(' ');
-                        if (piTarget == -1) {
-                            abortMarkup(XMLMessages.MSG_PITARGET_REQUIRED,
-                                        XMLMessages.P16_PITARGET_REQUIRED);
-                        } else if ("xml".equals(fStringPool.toString(piTarget))) {
-                            if (fEntityReader.lookingAtSpace(true)) { // an XMLDecl looks like a PI with the target 'xml'
-                                abortMarkup(XMLMessages.MSG_XMLDECL_MUST_BE_FIRST,
-                                            XMLMessages.P22_XMLDECL_MUST_BE_FIRST);
-                            } else { // a PI target matching 'xml'
-                                abortMarkup(XMLMessages.MSG_RESERVED_PITARGET,
-                                            XMLMessages.P17_RESERVED_PITARGET);
-                            }
-                        } else { // PI
-                            scanPI(piTarget);
-                        }
-                    } else if (fEntityReader.lookingAtChar('!', true)) {
-                        if (fEntityReader.lookingAtChar('-', true)) { // comment ?
-                            if (fEntityReader.lookingAtChar('-', true)) {
-                                scanComment(); // scan through the closing '-->'
-                            } else {
-                                abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_PROLOG,
-                                            XMLMessages.P22_NOT_RECOGNIZED);
-                            }
-                        } else {
-                            if (!fSeenDoctypeDecl && fEntityReader.skippedString(doctype_string)) {
-                                setScannerState(SCANNER_STATE_DOCTYPE);
-                                fSeenDoctypeDecl = true;
-                                scanDoctypeDecl(fStandalone); // scan through the closing '>'
-                                fScannerMarkupDepth--;
-                            } else {
-                                abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_PROLOG,
-                                            XMLMessages.P22_NOT_RECOGNIZED);
-                            }
-                        }
-                    } else {
-                        fDispatcher = new ContentDispatcher();
-                        restoreScannerState(SCANNER_STATE_ROOT_ELEMENT);
-                        return true;
-                    }
-                    restoreScannerState(SCANNER_STATE_PROLOG);
-                } else if (fEntityReader.lookingAtSpace(true)) {
-                    fEntityReader.skipPastSpaces();
-                } else if (!fEntityReader.lookingAtValidChar(false)) {
-                    int invChar = fEntityReader.scanInvalidChar();
-                    if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                        if (invChar >= 0) {
-                            String arg = Integer.toHexString(invChar);
-                            reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_PROLOG,
-                                                XMLMessages.P22_INVALID_CHARACTER,
-                                                arg);
-                        }
-                    }
-                } else {
-                    reportFatalXMLError(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_PROLOG,
-                                        XMLMessages.P22_NOT_RECOGNIZED);
-                    fEntityReader.lookingAtValidChar(true);
-                }
-            } while (fScannerState != SCANNER_STATE_END_OF_INPUT && keepgoing);
-            return true;
-        }
-        public void endOfInput(int entityName, boolean moreToFollow) throws Exception {
-            switch (fScannerState) {
-            case SCANNER_STATE_PROLOG:
-            case SCANNER_STATE_START_OF_MARKUP:
-            case SCANNER_STATE_DOCTYPE:
-                break;
-            case SCANNER_STATE_COMMENT:
-                if (!moreToFollow) {
-                    reportFatalXMLError(XMLMessages.MSG_COMMENT_UNTERMINATED,
-                                        XMLMessages.P15_UNTERMINATED);
-                } else {
-                    reportFatalXMLError(XMLMessages.MSG_COMMENT_NOT_IN_ONE_ENTITY,
-                                        XMLMessages.P78_NOT_WELLFORMED);
-                }
-                break;
-            case SCANNER_STATE_PI:
-                if (!moreToFollow) {
-                    reportFatalXMLError(XMLMessages.MSG_PI_UNTERMINATED,
-                                        XMLMessages.P16_UNTERMINATED);
-                } else {
-                    reportFatalXMLError(XMLMessages.MSG_PI_NOT_IN_ONE_ENTITY,
-                                        XMLMessages.P78_NOT_WELLFORMED);
-                }
-                break;
-            default:
-                throw new RuntimeException("FWK001 2] ScannerState="+fScannerState+"\n" + "2\t"+fScannerState);
-            }
-            if (!moreToFollow) {
-                reportFatalXMLError(XMLMessages.MSG_ROOT_ELEMENT_REQUIRED,
-                                    XMLMessages.P1_ELEMENT_REQUIRED);
-                fDispatcher = new EndOfInputDispatcher();
-                setScannerState(SCANNER_STATE_END_OF_INPUT);
-            }
-        }
-    }
-    int fCurrentElementType = -1;
-    public int getCurrentElementType() {
-        return fCurrentElementType;
-    }
-    final class ContentDispatcher implements ScannerDispatcher {
-        private int fContentReader = -1;
-        private int fElementDepth = 0;
-        private int[] fElementTypeStack = new int[8];
-
-        void popElementType() {
-            if (fElementDepth-- == 0) {
-                throw new RuntimeException("FWK002 popElementType: fElementDepth-- == 0.");
-            }
-            if (fElementDepth == 0) {
-                fCurrentElementType = - 1;
-            } else {
-                fCurrentElementType = fElementTypeStack[fElementDepth - 1];
-            }
-        }
-
-        public boolean dispatch(boolean keepgoing) throws Exception {
-            do {
-                switch (fScannerState) {
-                case SCANNER_STATE_ROOT_ELEMENT:
-                {
-                    scanElementType(fEntityReader, '>', fElementQName);
-                    if (fElementQName.rawname != -1) {
-                        //
-                        // root element
-                        //
-                        fContentReader = fReaderId;
-                        fSeenRootElement = true;
-                        //
-                        // scan element
-                        //
-                        if (fEntityReader.lookingAtChar('>', true)) {
-                            //
-                            // we have more content
-                            //
-                            fEventHandler.callStartElement(fElementQName);
-                            fScannerMarkupDepth--;
-                            if (fElementDepth == fElementTypeStack.length) {
-                                int[] newStack = new int[fElementDepth * 2];
-                                System.arraycopy(fElementTypeStack, 0, newStack, 0, fElementDepth);
-                                fElementTypeStack = newStack;
-                            }
-                            fCurrentElementType = fElementQName.rawname;
-                            fElementTypeStack[fElementDepth] = fElementQName.rawname;
-                            fElementDepth++;
-                            restoreScannerState(SCANNER_STATE_CONTENT);
-                        } else if (scanElement(fElementQName)) {
-                            //
-                            // we have more content
-                            //
-                            if (fElementDepth == fElementTypeStack.length) {
-                                int[] newStack = new int[fElementDepth * 2];
-                                System.arraycopy(fElementTypeStack, 0, newStack, 0, fElementDepth);
-                                fElementTypeStack = newStack;
-                            }
-                            fCurrentElementType = fElementQName.rawname;
-                            fElementTypeStack[fElementDepth] = fElementQName.rawname;
-                            fElementDepth++;
-                            restoreScannerState(SCANNER_STATE_CONTENT);
-                        } else {
-                            fDispatcher = new TrailingMiscDispatcher();
-                            restoreScannerState(SCANNER_STATE_TRAILING_MISC);
-                            return true;
-                        }
-                    } else {
-                        reportFatalXMLError(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_PROLOG,
-                                            XMLMessages.P22_NOT_RECOGNIZED);
-                        fDispatcher = new PrologDispatcher();
-                        restoreScannerState(SCANNER_STATE_PROLOG);
-                        return true;
-                    }
-                    break;
-                }
-                case SCANNER_STATE_START_OF_MARKUP:
-                    if (fEntityReader.lookingAtChar('?', true)) {
-                        int piTarget = fEntityReader.scanName(' ');
-                        if (piTarget == -1) {
-                            abortMarkup(XMLMessages.MSG_PITARGET_REQUIRED,
-                                        XMLMessages.P16_PITARGET_REQUIRED);
-                        } else if ("xml".equals(fStringPool.toString(piTarget))) {
-                            if (fEntityReader.lookingAtSpace(true)) { // an XMLDecl looks like a PI with the target 'xml'
-                                if (fParseTextDecl) {
-                                    scanXMLDeclOrTextDecl(true);
-                                    fParseTextDecl = false;
-                                } else {
-                                    abortMarkup(XMLMessages.MSG_TEXTDECL_MUST_BE_FIRST,
-                                                XMLMessages.P30_TEXTDECL_MUST_BE_FIRST);
-                                }
-                            } else { // a PI target matching 'xml'
-                                abortMarkup(XMLMessages.MSG_RESERVED_PITARGET,
-                                            XMLMessages.P17_RESERVED_PITARGET);
-                            }
-                        } else { // PI
-                            scanPI(piTarget);
-                        }
-                        restoreScannerState(SCANNER_STATE_CONTENT);
-                    } else if (fEntityReader.lookingAtChar('!', true)) {
-                        if (fEntityReader.lookingAtChar('-', true)) { // comment ?
-                            if (fEntityReader.lookingAtChar('-', true)) {
-                                scanComment(); // scan through the closing '-->'
-                            } else {
-                                abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_CONTENT,
-                                            XMLMessages.P43_NOT_RECOGNIZED);
-                            }
-                        } else {
-                            if (fEntityReader.skippedString(cdata_string)) {
-                                fEntityReader.setInCDSect(true);
-                                fEventHandler.callStartCDATA();
-                            } else {
-                                abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_CONTENT,
-                                            XMLMessages.P43_NOT_RECOGNIZED);
-                            }
-                        }
-                    } else {
-                        if (fEntityReader.lookingAtChar('/', true)) {
-                            //
-                            // [42] ETag ::= '</' Name S? '>'
-                            //
-                            if (!scanExpectedElementType(fEntityReader, '>', fCurrentElementType)) {
-                                abortMarkup(XMLMessages.MSG_ETAG_REQUIRED,
-                                            XMLMessages.P39_UNTERMINATED,
-                                            fCurrentElementType);
-                            } else {
-                                if (!fEntityReader.lookingAtChar('>', true)) {
-                                    fEntityReader.skipPastSpaces();
-                                    if (!fEntityReader.lookingAtChar('>', true)) {
-                                        reportFatalXMLError(XMLMessages.MSG_ETAG_UNTERMINATED,
-                                                            XMLMessages.P42_UNTERMINATED,
-                                                            fCurrentElementType);
-                                    }
-                                }
-                                fScannerMarkupDepth--;
-                                fEventHandler.callEndElement(fReaderId);
-                                if (fElementDepth-- == 0) {
-                                    throw new RuntimeException("FWK002 popElementType: fElementDepth-- == 0.");
-                                }
-                                if (fElementDepth == 0) {
-                                    fCurrentElementType = - 1;
-                                    fDispatcher = new TrailingMiscDispatcher();
-                                    restoreScannerState(SCANNER_STATE_TRAILING_MISC);
-                                    return true;
-                                } else {
-                                    fCurrentElementType = fElementTypeStack[fElementDepth - 1];
-                                }
-                            }
-                        } else {
-                            scanElementType(fEntityReader, '>', fElementQName);
-                            if (fElementQName.rawname != -1) {
-                                //
-                                // element
-                                //
-                                if (fEntityReader.lookingAtChar('>', true)) {
-                                    fEventHandler.callStartElement(fElementQName);
-                                    fScannerMarkupDepth--;
-                                    if (fElementDepth == fElementTypeStack.length) {
-                                        int[] newStack = new int[fElementDepth * 2];
-                                        System.arraycopy(fElementTypeStack, 0, newStack, 0, fElementDepth);
-                                        fElementTypeStack = newStack;
-                                    }
-                                    fCurrentElementType = fElementQName.rawname;
-                                    fElementTypeStack[fElementDepth] = fElementQName.rawname;
-                                    fElementDepth++;
-                                } else {
-                                    if (scanElement(fElementQName)) {
-                                        if (fElementDepth == fElementTypeStack.length) {
-                                            int[] newStack = new int[fElementDepth * 2];
-                                            System.arraycopy(fElementTypeStack, 0, newStack, 0, fElementDepth);
-                                            fElementTypeStack = newStack;
-                                        }
-                                        fCurrentElementType = fElementQName.rawname;
-                                        fElementTypeStack[fElementDepth] = fElementQName.rawname;
-                                        fElementDepth++;
-                                    }
-                                }
-                            } else {
-                                abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_CONTENT,
-                                            XMLMessages.P43_NOT_RECOGNIZED);
-                            }
-                        }
-                    }
-                    restoreScannerState(SCANNER_STATE_CONTENT);
-                    break;
-                case SCANNER_STATE_CONTENT:
-                    if (fParseTextDecl && fEntityReader.lookingAtChar('<', true)) {
-                        fScannerMarkupDepth++;
-                        setScannerState(SCANNER_STATE_START_OF_MARKUP);
-                        continue;
-                    }
-                    // REVISIT: Is this the right thing to do? Do we need to
-                    //          save more information on the stack?
-                    fCurrentElementQName.setValues(-1, -1, fCurrentElementType);
-                    switch (fEntityReader.scanContent(fCurrentElementQName)) {
-                    case XMLEntityHandler.CONTENT_RESULT_START_OF_PI:
-                        fScannerMarkupDepth++;
-                        int piTarget = fEntityReader.scanName(' ');
-                        if (piTarget == -1) {
-                            abortMarkup(XMLMessages.MSG_PITARGET_REQUIRED,
-                                        XMLMessages.P16_PITARGET_REQUIRED);
-                        } else if ("xml".equals(fStringPool.toString(piTarget))) {
-                            if (fEntityReader.lookingAtSpace(true)) { // an XMLDecl looks like a PI with the target 'xml'
-                                if (fReaderId == fContentReader) {
-                                    abortMarkup(XMLMessages.MSG_XMLDECL_MUST_BE_FIRST,
-                                                XMLMessages.P22_XMLDECL_MUST_BE_FIRST);
-                                } else {
-                                    abortMarkup(XMLMessages.MSG_TEXTDECL_MUST_BE_FIRST,
-                                                XMLMessages.P30_TEXTDECL_MUST_BE_FIRST);
-                                }
-                            } else { // a PI target matching 'xml'
-                                abortMarkup(XMLMessages.MSG_RESERVED_PITARGET,
-                                            XMLMessages.P17_RESERVED_PITARGET);
-                            }
-                        } else { // PI
-                            scanPI(piTarget);
-                        }
-                        break;
-                    case XMLEntityHandler.CONTENT_RESULT_START_OF_COMMENT:
-                        fScannerMarkupDepth++;
-                        fParseTextDecl = false;
-                        scanComment(); // scan through the closing '-->'
-                        break;
-                    case XMLEntityHandler.CONTENT_RESULT_START_OF_CDSECT:
-                        fScannerMarkupDepth++;
-                        fParseTextDecl = false;
-                        fEntityReader.setInCDSect(true);
-                        fEventHandler.callStartCDATA();
-                        break;
-                    case XMLEntityHandler.CONTENT_RESULT_START_OF_ETAG:
-                        fScannerMarkupDepth++;
-                        fParseTextDecl = false;
-                        //
-                        // [42] ETag ::= '</' Name S? '>'
-                        //
-                        if (!scanExpectedElementType(fEntityReader, '>', fCurrentElementType)) {
-                            abortMarkup(XMLMessages.MSG_ETAG_REQUIRED,
-                                        XMLMessages.P39_UNTERMINATED,
-                                        fCurrentElementType);
-                        } else {
-                            if (!fEntityReader.lookingAtChar('>', true)) {
-                                fEntityReader.skipPastSpaces();
-                                if (!fEntityReader.lookingAtChar('>', true)) {
-                                    reportFatalXMLError(XMLMessages.MSG_ETAG_UNTERMINATED,
-                                                        XMLMessages.P42_UNTERMINATED,
-                                                        fCurrentElementType);
-                                }
-                            }
-                            fScannerMarkupDepth--;
-                            fEventHandler.callEndElement(fReaderId);
-                            if (fElementDepth-- == 0) {
-                                throw new RuntimeException("FWK002 popElementType: fElementDepth-- == 0.");
-                            }
-                            if (fElementDepth == 0) {
-                                fCurrentElementType = - 1;
-                                fDispatcher = new TrailingMiscDispatcher();
-                                restoreScannerState(SCANNER_STATE_TRAILING_MISC);
-                                return true;
-                            } else {
-                                fCurrentElementType = fElementTypeStack[fElementDepth - 1];
-                            }
-                        }
-                        restoreScannerState(SCANNER_STATE_CONTENT);
-                        break;
-                    case XMLEntityHandler.CONTENT_RESULT_START_OF_ELEMENT:
-                    {
-                        fScannerMarkupDepth++;
-                        fParseTextDecl = false;
-                        scanElementType(fEntityReader, '>', fElementQName);
-                        if (fElementQName.rawname != -1) {
-                            if (fEntityReader.lookingAtChar('>', true)) {
-                                fEventHandler.callStartElement(fElementQName);
-                                fScannerMarkupDepth--;
-                                if (fElementDepth == fElementTypeStack.length) {
-                                    int[] newStack = new int[fElementDepth * 2];
-                                    System.arraycopy(fElementTypeStack, 0, newStack, 0, fElementDepth);
-                                    fElementTypeStack = newStack;
-                                }
-                                fCurrentElementType = fElementQName.rawname;
-                                fElementTypeStack[fElementDepth] = fElementQName.rawname;
-                                fElementDepth++;
-                            } else {
-                                if (scanElement(fElementQName)) {
-                                    if (fElementDepth == fElementTypeStack.length) {
-                                        int[] newStack = new int[fElementDepth * 2];
-                                        System.arraycopy(fElementTypeStack, 0, newStack, 0, fElementDepth);
-                                        fElementTypeStack = newStack;
-                                    }
-                                    fCurrentElementType = fElementQName.rawname;
-                                    fElementTypeStack[fElementDepth] = fElementQName.rawname;
-                                    fElementDepth++;
-                                }
-                            }
-                        } else {
-                            abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_CONTENT,
-                                        XMLMessages.P43_NOT_RECOGNIZED);
-                        }
-                        if (fScannerState != SCANNER_STATE_END_OF_INPUT)
-                            fScannerState = SCANNER_STATE_CONTENT;
-                        break;
-                    }
-                    case XMLEntityHandler.CONTENT_RESULT_MATCHING_ETAG:
-                    {
-                        fParseTextDecl = false;
-                        fEventHandler.callEndElement(fReaderId);
-                        if (fElementDepth-- == 0) {
-                            throw new RuntimeException("FWK002 popElementType: fElementDepth-- == 0.");
-                        }
-                        if (fElementDepth == 0) {
-                            fCurrentElementType = - 1;
-                            if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                                fDispatcher = new TrailingMiscDispatcher();
-                                fScannerState = SCANNER_STATE_TRAILING_MISC;
-                            }
-                            return true;
-                        } else {
-                            fCurrentElementType = fElementTypeStack[fElementDepth - 1];
-                        }
-                        if (fScannerState != SCANNER_STATE_END_OF_INPUT)
-                            fScannerState = SCANNER_STATE_CONTENT;
-                        break;
-                    }
-                    case XMLEntityHandler.CONTENT_RESULT_START_OF_CHARREF:
-                        fParseTextDecl = false;
-                        //
-                        // [67] Reference ::= EntityRef | CharRef
-                        // [68] EntityRef ::= '&' Name ';'
-                        // [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
-                        //
-                        setScannerState(SCANNER_STATE_REFERENCE);
-                        int num = scanCharRef();
-                        // if (num == -1) num = 0xfffd; // REVISIT - alternative is to use Unicode replacement char
-                        if (num != -1)
-                            fEventHandler.callCharacters(num);
-                        restoreScannerState(SCANNER_STATE_CONTENT);
-                        break;
-                    case XMLEntityHandler.CONTENT_RESULT_REFERENCE_END_OF_INPUT:
-                        // REVISIT - This should hopefully get us the "reference not
-                        //   contained in one entity" error when endOfInput is called.
-                        //   Test that this is so...
-                        //
-                        // fall through...
-                        //
-                    case XMLEntityHandler.CONTENT_RESULT_START_OF_ENTITYREF:
-                        fParseTextDecl = false;
-                        //
-                        // [68] EntityRef ::= '&' Name ';'
-                        //
-                        setScannerState(SCANNER_STATE_REFERENCE);
-                        int nameOffset = fEntityReader.currentOffset();
-                        fEntityReader.skipPastName(';');
-                        int nameLength = fEntityReader.currentOffset() - nameOffset;
-                        if (nameLength == 0) {
-                            reportFatalXMLError(XMLMessages.MSG_NAME_REQUIRED_IN_REFERENCE,
-                                                XMLMessages.P68_NAME_REQUIRED);
-                            restoreScannerState(SCANNER_STATE_CONTENT);
-                        } else if (!fEntityReader.lookingAtChar(';', true)) {
-                            reportFatalXMLError(XMLMessages.MSG_SEMICOLON_REQUIRED_IN_REFERENCE,
-                                                XMLMessages.P68_SEMICOLON_REQUIRED,
-                                                fEntityReader.addString(nameOffset, nameLength));
-                            restoreScannerState(SCANNER_STATE_CONTENT);
-                        } else {
-                            restoreScannerState(SCANNER_STATE_CONTENT);
-                            int entityName = fEntityReader.addSymbol(nameOffset, nameLength);
-                            fParseTextDecl = fEntityHandler.startReadingFromEntity(entityName, fElementDepth, XMLEntityHandler.ENTITYREF_IN_CONTENT);
-                        }
-                        break;
-                    case XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT:
-                        fParseTextDecl = false;
-                        //
-                        // [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
-                        // [21] CDEnd ::= ']]>'
-                        //
-                        if (fEntityReader.getInCDSect()) {
-                            fEntityReader.setInCDSect(false);
-                            fEventHandler.callEndCDATA();
-                            fScannerMarkupDepth--;
-                        } else {
-                            reportFatalXMLError(XMLMessages.MSG_CDEND_IN_CONTENT,
-                                                XMLMessages.P14_INVALID);
-                        }
-                        restoreScannerState(SCANNER_STATE_CONTENT);
-                        break;
-                    case XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR:
-                        fParseTextDecl = false;
-                        //
-                        // The reader will also use this state if it
-                        // encounters the end of input while reading
-                        // content.  We need to check for this case.
-                        //
-                        if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                            if (!fEntityReader.lookingAtValidChar(false)) {
-                                //
-                                //  [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF]        // any Unicode character, excluding the
-                                //               | [#xE000-#xFFFD] | [#x10000-#x10FFFF] // surrogate blocks, FFFE, and FFFF.
-                                //
-                                int invChar = fEntityReader.scanInvalidChar();
-                                if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                                    if (invChar >= 0) {
-                                        if (fEntityReader.getInCDSect()) {
-                                            reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_CDSECT,
-                                                                XMLMessages.P20_INVALID_CHARACTER,
-                                                                Integer.toHexString(invChar));
-                                        } else {
-                                            reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_CONTENT,
-                                                                XMLMessages.P43_INVALID_CHARACTER,
-                                                                Integer.toHexString(invChar));
-                                        }
-                                    }
-                                }
-                            }
-                            restoreScannerState(SCANNER_STATE_CONTENT);
-                        }
-                        break;
-                    case XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED:
-                        fParseTextDecl = false;
-                        abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_CONTENT,
-                                    XMLMessages.P43_NOT_RECOGNIZED);
-                        break;
-                    case XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT:
-                        // REVISIT - This should hopefully get us the "markup not
-                        //   contained in one entity" error when endOfInput is called.
-                        //   Test that this is so...
-                        fScannerMarkupDepth++;
-                        fParseTextDecl = false;
-                        fScannerState = SCANNER_STATE_START_OF_MARKUP;
-                        break;
-                    default:
-                        throw new RuntimeException("FWK001 3] ScannerState="+fScannerState+"\n" + "3\t"+fScannerState); // should not happen
-                    }
-                    break;
-                default:
-                    throw new RuntimeException("FWK001 4] ScannerState="+fScannerState+"\n" + "4\t"+fScannerState);
-                }
-            } while (fScannerState != SCANNER_STATE_END_OF_INPUT && keepgoing);
-            return true;
-        }
-        public void endOfInput(int entityName, boolean moreToFollow) throws Exception {
-            switch (fScannerState) {
-            case SCANNER_STATE_ROOT_ELEMENT:
-            case SCANNER_STATE_START_OF_MARKUP:
-                break;
-            case SCANNER_STATE_CONTENT:
-                if (fEntityReader.getInCDSect()) {
-                    reportFatalXMLError(XMLMessages.MSG_CDSECT_UNTERMINATED,
-                                        XMLMessages.P18_UNTERMINATED);
-                }
-                break;
-            case SCANNER_STATE_ATTRIBUTE_LIST:
-                if (!moreToFollow) {
-// REVISIT                    reportFatalXMLError(XMLMessages.MSG_TAG1);
-                } else {
-// REVISIT                    reportFatalXMLError(XMLMessages.MSG_TAG1);
-                }
-                break;
-            case SCANNER_STATE_ATTRIBUTE_NAME:
-                if (!moreToFollow) {
-// REVISIT                    reportFatalXMLError(XMLMessages.MSG_ATTVAL0);
-                } else {
-// REVISIT                    reportFatalXMLError(XMLMessages.MSG_ATTVAL0);
-                }
-                break;
-            case SCANNER_STATE_ATTRIBUTE_VALUE:
-                if (!moreToFollow) {
-                    reportFatalXMLError(XMLMessages.MSG_ATTRIBUTE_VALUE_UNTERMINATED,
-                                        XMLMessages.P10_UNTERMINATED,
-                                        fAttValueElementType,
-                                        fAttValueAttrName);
-                } else if (fReaderId == fAttValueReader) {
-// REVISIT                        reportFatalXMLError(XMLMessages.MSG_ATTVAL0);
-                } else {
-                    fEntityReader.append(fLiteralData, fAttValueMark, fAttValueOffset - fAttValueMark);
-                }
-                break;
-            case SCANNER_STATE_COMMENT:
-                if (!moreToFollow) {
-                    reportFatalXMLError(XMLMessages.MSG_COMMENT_UNTERMINATED,
-                                        XMLMessages.P15_UNTERMINATED);
-                } else {
-                    reportFatalXMLError(XMLMessages.MSG_COMMENT_NOT_IN_ONE_ENTITY,
-                                        XMLMessages.P78_NOT_WELLFORMED);
-                }
-                break;
-            case SCANNER_STATE_PI:
-                if (!moreToFollow) {
-                    reportFatalXMLError(XMLMessages.MSG_PI_UNTERMINATED,
-                                        XMLMessages.P16_UNTERMINATED);
-                } else {
-                    reportFatalXMLError(XMLMessages.MSG_PI_NOT_IN_ONE_ENTITY,
-                                        XMLMessages.P78_NOT_WELLFORMED);
-                }
-                break;
-            case SCANNER_STATE_REFERENCE:
-                if (!moreToFollow) {
-                    reportFatalXMLError(XMLMessages.MSG_REFERENCE_UNTERMINATED,
-                                        XMLMessages.P67_UNTERMINATED);
-                } else {
-                    reportFatalXMLError(XMLMessages.MSG_REFERENCE_NOT_IN_ONE_ENTITY,
-                                        XMLMessages.P78_NOT_WELLFORMED);
-                }
-                break;
-            default:
-                throw new RuntimeException("FWK001 5] ScannerState="+fScannerState+"\n" + "5\t"+fScannerState);
-            }
-            if (!moreToFollow) {
-                if (fElementDepth > 0)
-                    reportFatalXMLError(XMLMessages.MSG_ETAG_REQUIRED,
-                                        XMLMessages.P39_UNTERMINATED,
-                                        fCurrentElementType);
-                fDispatcher = new EndOfInputDispatcher();
-                setScannerState(SCANNER_STATE_END_OF_INPUT);
-            }
-        }
-    }
-    final class TrailingMiscDispatcher implements ScannerDispatcher {
-        public boolean dispatch(boolean keepgoing) throws Exception {
-            do {
-                if (fEntityReader.lookingAtChar('<', true)) {
-                    fScannerMarkupDepth++;
-                    setScannerState(SCANNER_STATE_START_OF_MARKUP);
-                    if (fEntityReader.lookingAtChar('?', true)) {
-                        int piTarget = fEntityReader.scanName(' ');
-                        if (piTarget == -1) {
-                            abortMarkup(XMLMessages.MSG_PITARGET_REQUIRED,
-                                        XMLMessages.P16_PITARGET_REQUIRED);
-                        } else if ("xml".equals(fStringPool.toString(piTarget))) {
-                            if (fEntityReader.lookingAtSpace(true)) { // an XMLDecl looks like a PI with the target 'xml'
-                                abortMarkup(XMLMessages.MSG_XMLDECL_MUST_BE_FIRST,
-                                            XMLMessages.P22_XMLDECL_MUST_BE_FIRST);
-                            } else { // a PI target matching 'xml'
-                                abortMarkup(XMLMessages.MSG_RESERVED_PITARGET,
-                                            XMLMessages.P17_RESERVED_PITARGET);
-                            }
-                        } else { // PI
-                            scanPI(piTarget);
-                        }
-                    } else if (fEntityReader.lookingAtChar('!', true)) {
-                        if (fEntityReader.lookingAtChar('-', true) &&
-                            fEntityReader.lookingAtChar('-', true)) { // comment ?
-                            scanComment(); // scan through the closing '-->'
-                        } else {
-                            abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_MISC,
-                                        XMLMessages.P27_NOT_RECOGNIZED);
-                        }
-                    } else {
-                        abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_MISC,
-                                    XMLMessages.P27_NOT_RECOGNIZED);
-                    }
-                    restoreScannerState(SCANNER_STATE_TRAILING_MISC);
-                } else if (fEntityReader.lookingAtSpace(true)) {
-                    fEntityReader.skipPastSpaces();
-                } else if (!fEntityReader.lookingAtValidChar(false)) {
-                    int invChar = fEntityReader.scanInvalidChar();
-                    if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                        if (invChar >= 0) {
-                            String arg = Integer.toHexString(invChar);
-                            reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_MISC,
-                                                XMLMessages.P27_INVALID_CHARACTER,
-                                                arg);
-                        }
-                    }
-                } else {
-                    reportFatalXMLError(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_MISC,
-                                        XMLMessages.P27_NOT_RECOGNIZED);
-                    fEntityReader.lookingAtValidChar(true);
-                }
-            } while (fScannerState != SCANNER_STATE_END_OF_INPUT && keepgoing);
-            return true;
-        }
-        public void endOfInput(int entityName, boolean moreToFollow) throws Exception {
-            if (moreToFollow)
-                throw new RuntimeException("FWK003 TrailingMiscDispatcher.endOfInput moreToFollow");
-            switch (fScannerState) {
-            case SCANNER_STATE_TRAILING_MISC:
-            case SCANNER_STATE_START_OF_MARKUP:
-                break;
-            case SCANNER_STATE_COMMENT:
-                reportFatalXMLError(XMLMessages.MSG_COMMENT_UNTERMINATED,
-                                    XMLMessages.P15_UNTERMINATED);
-                break;
-            case SCANNER_STATE_PI:
-                reportFatalXMLError(XMLMessages.MSG_PI_UNTERMINATED,
-                                    XMLMessages.P16_UNTERMINATED);
-                break;
-            default:
-                throw new RuntimeException("FWK001 6] ScannerState="+fScannerState+"\n" + "6\t"+fScannerState);
-            }
-            fDispatcher = new EndOfInputDispatcher();
-            setScannerState(SCANNER_STATE_END_OF_INPUT);
-        }
-    }
-    final class EndOfInputDispatcher implements ScannerDispatcher {
-        public boolean dispatch(boolean keepgoing) throws Exception {
-            if (fScannerState != SCANNER_STATE_TERMINATED)
-                fEventHandler.callEndDocument();
-            setScannerState(SCANNER_STATE_TERMINATED);
-            return false;
-        }
-        public void endOfInput(int entityName, boolean moreToFollow) throws Exception {
-            throw new RuntimeException("FWK001 7] ScannerState="+fScannerState+"\n" + "7\t"+fScannerState);
-        }
-    }
-    //
-    // From the standard:
-    //
-    // [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
-    // [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
-    // [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'" )
-    // [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
-    // [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'")
-    //                 | ('"' ('yes' | 'no') '"'))
-    //
-    // [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
-    //
-    void scanXMLDeclOrTextDecl(boolean scanningTextDecl) throws Exception
-    {
-        int version = -1;
-        int encoding = -1;
-        int standalone = -1;
-        final int XMLDECL_START = 0;
-        final int XMLDECL_VERSION = 1;
-        final int XMLDECL_ENCODING = 2;
-        final int XMLDECL_STANDALONE = 3;
-        final int XMLDECL_FINISHED = 4;
-        int state = XMLDECL_START;
-        do {
-            fEntityReader.skipPastSpaces();
-            int offset = fEntityReader.currentOffset();
-            if (scanningTextDecl) {
-                if (state == XMLDECL_START && fEntityReader.skippedString(version_string)) {
-                    state = XMLDECL_VERSION;
-                } else if (fEntityReader.skippedString(encoding_string)) {
-                    state = XMLDECL_ENCODING;
-                } else {
-                    abortMarkup(XMLMessages.MSG_ENCODINGDECL_REQUIRED,
-                                XMLMessages.P77_ENCODINGDECL_REQUIRED);
-                    return;
-                }
-            } else {
-                if (state == XMLDECL_START) {
-                    if (!fEntityReader.skippedString(version_string)) {
-                        abortMarkup(XMLMessages.MSG_VERSIONINFO_REQUIRED,
-                                    XMLMessages.P23_VERSIONINFO_REQUIRED);
-                        return;
-                    }
-                    state = XMLDECL_VERSION;
-                } else {
-                    if (state == XMLDECL_VERSION) {
-                        if (fEntityReader.skippedString(encoding_string))
-                            state = XMLDECL_ENCODING;
-                        else
-                            state = XMLDECL_STANDALONE;
-                    } else
-                        state = XMLDECL_STANDALONE;
-                    if (state == XMLDECL_STANDALONE && !fEntityReader.skippedString(standalone_string))
-                        break;
-                }
-            }
-            int length = fEntityReader.currentOffset() - offset;
-            fEntityReader.skipPastSpaces();
-            if (!fEntityReader.lookingAtChar('=', true)) {
-                int majorCode = scanningTextDecl ?
-                                XMLMessages.MSG_EQ_REQUIRED_IN_TEXTDECL :
-                                XMLMessages.MSG_EQ_REQUIRED_IN_XMLDECL;
-                int minorCode = state == XMLDECL_VERSION ?
-                                XMLMessages.P24_EQ_REQUIRED :
-                                (state == XMLDECL_ENCODING ?
-                                 XMLMessages.P80_EQ_REQUIRED :
-                                 XMLMessages.P32_EQ_REQUIRED);
-                abortMarkup(majorCode, minorCode, fEntityReader.addString(offset, length));
-                return;
-            }
-            fEntityReader.skipPastSpaces();
-            int result = fEntityReader.scanStringLiteral();
-            switch (result) {
-            case XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED:
-            {
-                int majorCode = scanningTextDecl ?
-                                XMLMessages.MSG_QUOTE_REQUIRED_IN_TEXTDECL :
-                                XMLMessages.MSG_QUOTE_REQUIRED_IN_XMLDECL;
-                int minorCode = state == XMLDECL_VERSION ?
-                                XMLMessages.P24_QUOTE_REQUIRED :
-                                (state == XMLDECL_ENCODING ?
-                                 XMLMessages.P80_QUOTE_REQUIRED :
-                                 XMLMessages.P32_QUOTE_REQUIRED);
-                abortMarkup(majorCode, minorCode, fEntityReader.addString(offset, length));
-                return;
-            }
-            case XMLEntityHandler.STRINGLIT_RESULT_INVALID_CHAR:
-                int invChar = fEntityReader.scanInvalidChar();
-                if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                    if (invChar >= 0) {
-                        int majorCode = scanningTextDecl ?
-                                        XMLMessages.MSG_INVALID_CHAR_IN_TEXTDECL :
-                                        XMLMessages.MSG_INVALID_CHAR_IN_XMLDECL;
-                        int minorCode = state == XMLDECL_VERSION ?
-                                        XMLMessages.P26_INVALID_CHARACTER :
-                                        (state == XMLDECL_ENCODING ?
-                                         XMLMessages.P81_INVALID_CHARACTER :
-                                         XMLMessages.P32_INVALID_CHARACTER);
-                        reportFatalXMLError(majorCode, minorCode, Integer.toHexString(invChar));
-                    }
-                    skipPastEndOfCurrentMarkup();
-                }
-                return;
-            default:
-                break;
-            }
-            switch (state) {
-            case XMLDECL_VERSION:
-                //
-                // version="..."
-                //
-                version = result;
-                String versionString = fStringPool.toString(version);
-                if (!"1.0".equals(versionString)) {
-                    if (!validVersionNum(versionString)) {
-                        abortMarkup(XMLMessages.MSG_VERSIONINFO_INVALID,
-                                            XMLMessages.P26_INVALID_VALUE,
-                                            versionString);
-                        return;
-                    }
-                    // NOTE: RECOVERABLE ERROR
-                    Object[] args = { versionString };
-                    fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                               XMLMessages.XML_DOMAIN,
-                                               XMLMessages.MSG_VERSION_NOT_SUPPORTED,
-                                               XMLMessages.P26_NOT_SUPPORTED,
-                                               args,
-                                               XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                    // REVISIT - hope it is compatible...
-                    // skipPastEndOfCurrentMarkup();
-                    // return;
-                }
-                if (!fEntityReader.lookingAtSpace(true)) {
-                    if (scanningTextDecl) {
-                        abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_IN_TEXTDECL,
-                                    XMLMessages.P80_WHITESPACE_REQUIRED);
-                        return;
-                    }
-                    state = XMLDECL_FINISHED;
-                }
-                break;
-            case XMLDECL_ENCODING:
-                //
-                // encoding = "..."
-                //
-                encoding = result;
-                String encodingString = fStringPool.toString(encoding);
-                if (!validEncName(encodingString)) {
-                    abortMarkup(XMLMessages.MSG_ENCODINGDECL_INVALID,
-                                XMLMessages.P81_INVALID_VALUE,
-                                encodingString);
-                    return;
-                }
-                if (!fEntityReader.lookingAtSpace(true)) {
-                    state = XMLDECL_FINISHED;
-                } else if (scanningTextDecl) {
-                    fEntityReader.skipPastSpaces();
-                    state = XMLDECL_FINISHED;
-                }
-                break;
-            case XMLDECL_STANDALONE:
-                //
-                // standalone="..."
-                //
-                standalone = result;
-                String standaloneString = fStringPool.toString(standalone);
-                boolean yes = "yes".equals(standaloneString);
-                if (!yes && !"no".equals(standaloneString)) {
-                    abortMarkup(XMLMessages.MSG_SDDECL_INVALID,
-                                XMLMessages.P32_INVALID_VALUE,
-                                standaloneString);
-                    return;
-                }
-                fStandalone = yes;
-                fEntityReader.skipPastSpaces();
-                state = XMLDECL_FINISHED;
-                break;
-            }
-        } while (state != XMLDECL_FINISHED);
-        if (!fEntityReader.lookingAtChar('?', true) || !fEntityReader.lookingAtChar('>', true)) {
-            int majorCode, minorCode;
-            if (scanningTextDecl) {
-                majorCode = XMLMessages.MSG_TEXTDECL_UNTERMINATED;
-                minorCode = XMLMessages.P77_UNTERMINATED;
-            } else {
-                majorCode = XMLMessages.MSG_XMLDECL_UNTERMINATED;
-                minorCode = XMLMessages.P23_UNTERMINATED;
-            }
-            abortMarkup(majorCode, minorCode);
-            return;
-        }
-        fScannerMarkupDepth--;
-        if (scanningTextDecl) {
-            fEventHandler.callTextDecl(version, encoding);
-        } else {
-            //
-            // Now that we have hit '?>' we are done with XML decl. Call the
-            // handler before returning.
-            //
-            fEventHandler.callXMLDecl(version, encoding, standalone);
-            // if we see standalone = 'yes', call the eventHandler - XMLValidator
-            if (fStandalone) {
-                fEventHandler.callStandaloneIsYes();
-            }
-        }
-    }
-    //
-    // From the standard:
-    //
-    // [39] element ::= EmptyElemTag | STag content ETag
-    // [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
-    // [40] STag ::= '<' Name (S Attribute)* S? '>'
-    // [41] Attribute ::= Name Eq AttValue
-    // [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
-    // [67] Reference ::= EntityRef | CharRef
-    // [68] EntityRef ::= '&' Name ';'
-    // [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
-    // [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
-    // [42] ETag ::= '</' Name S? '>'
-    //
-    // Note: We have already scanned Name.
-    //
-    boolean scanElement(QName element) throws Exception
-    {
-        //
-        // Scan for attributes
-        //
-        boolean greater = false;
-        boolean slash = false;
-        if (greater = fEntityReader.lookingAtChar('>', true)) {
-            // no attributes
-        } else if (fEntityReader.lookingAtSpace(true)) {
-            int previousState = setScannerState(SCANNER_STATE_ATTRIBUTE_LIST);
-            while (true) {
-                fEntityReader.skipPastSpaces();
-                //
-                // [41] Attribute ::= Name Eq AttValue
-                //
-                if ((greater = fEntityReader.lookingAtChar('>', true)) || (slash = fEntityReader.lookingAtChar('/', true)))
-                    break;
-                //
-                // Name
-                //
-                setScannerState(SCANNER_STATE_ATTRIBUTE_NAME);
-                scanAttributeName(fEntityReader, element, fAttributeQName);
-                if (fAttributeQName.rawname == -1) {
-                    break;
-                }
-                //
-                // Eq
-                //
-                fEntityReader.skipPastSpaces();
-                if (!fEntityReader.lookingAtChar('=', true)) {
-                    if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                        abortMarkup(XMLMessages.MSG_EQ_REQUIRED_IN_ATTRIBUTE,
-                                    XMLMessages.P41_EQ_REQUIRED,
-                                    element.rawname, fAttributeQName.rawname);
-                        restoreScannerState(previousState);
-                    }
-                    return false;
-                }
-                fEntityReader.skipPastSpaces();
-                int result = scanAttValue(element, fAttributeQName, false);
-                if (result == RESULT_FAILURE) {
-                    if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                        skipPastEndOfCurrentMarkup();
-                        restoreScannerState(previousState);
-                    }
-                    return false;
-                } else if (result == RESULT_DUPLICATE_ATTR) {
-                    reportFatalXMLError(XMLMessages.MSG_ATTRIBUTE_NOT_UNIQUE,
-                                        XMLMessages.WFC_UNIQUE_ATT_SPEC,
-                                        element.rawname, fAttributeQName.rawname);
-                }
-                //The validator will check whether we have a duplicate attr in the start tag.
-                if ( fEventHandler.attribute(element, fAttributeQName, result) ) {
-                    reportFatalXMLError(XMLMessages.MSG_ATTRIBUTE_NOT_UNIQUE,
-                                        XMLMessages.WFC_UNIQUE_ATT_SPEC,
-                                        element.rawname, fAttributeQName.rawname);
-                }
-                restoreScannerState(SCANNER_STATE_ATTRIBUTE_LIST);
-                if (!fEntityReader.lookingAtSpace(true)) {
-                    if (!(greater = fEntityReader.lookingAtChar('>', true)))
-                        slash = fEntityReader.lookingAtChar('/', true);
-                    break;
-                }
-            }
-            restoreScannerState(previousState);
-        } else {
-            slash = fEntityReader.lookingAtChar('/', true);
-        }
-        if (!greater && (!slash || !fEntityReader.lookingAtChar('>', true))) { // '>' or '/>'
-            if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                abortMarkup(XMLMessages.MSG_ELEMENT_UNTERMINATED,
-                            XMLMessages.P40_UNTERMINATED,
-                            element.rawname);
-            }
-            return false;
-        }
-        fEventHandler.callStartElement(element);
-        fScannerMarkupDepth--;
-        if (slash) { // '/>'
-            fEventHandler.callEndElement(fReaderId);
-            return false;
-        } else {
-            return true;
-        }
-    }
-    //
-    // [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
-    //
-    int scanCharRef() throws Exception {
-        int valueOffset = fEntityReader.currentOffset();
-        boolean hex = fEntityReader.lookingAtChar('x', true);
-        int num = fEntityReader.scanCharRef(hex);
-        if (num < 0) {
-            switch (num) {
-            case XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED:
-                reportFatalXMLError(XMLMessages.MSG_SEMICOLON_REQUIRED_IN_CHARREF,
-                                    XMLMessages.P66_SEMICOLON_REQUIRED);
-                return -1;
-            case XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR:
-                int majorCode = hex ? XMLMessages.MSG_HEXDIGIT_REQUIRED_IN_CHARREF :
-                                      XMLMessages.MSG_DIGIT_REQUIRED_IN_CHARREF;
-                int minorCode = hex ? XMLMessages.P66_HEXDIGIT_REQUIRED :
-                                      XMLMessages.P66_DIGIT_REQUIRED;
-                reportFatalXMLError(majorCode, minorCode);
-                return -1;
-            case XMLEntityHandler.CHARREF_RESULT_OUT_OF_RANGE:
-                num = 0x110000; // this will cause the right error to be reported below...
-                break;
-            }
-        }
-        //
-        //  [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF]        // any Unicode character, excluding the
-        //               | [#xE000-#xFFFD] | [#x10000-#x10FFFF] // surrogate blocks, FFFE, and FFFF.
-        //
-        if (num < 0x20) {
-            if (num == 0x09 || num == 0x0A || num == 0x0D) {
-                return num;
-            }
-        } else if (num <= 0xD7FF || (num >= 0xE000 && (num <= 0xFFFD || (num >= 0x10000 && num <= 0x10FFFF)))) {
-            return num;
-        }
-        int valueLength = fEntityReader.currentOffset() - valueOffset;
-        reportFatalXMLError(XMLMessages.MSG_INVALID_CHARREF,
-                            XMLMessages.WFC_LEGAL_CHARACTER,
-                            fEntityReader.addString(valueOffset, valueLength));
-        return -1;
-    }
-    //
-    // From the standard:
-    //
-    // [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
-    //
-    // Called after scanning past '<!--'
-    //
-    void scanComment() throws Exception
-    {
-        int commentOffset = fEntityReader.currentOffset();
-        boolean sawDashDash = false;
-        int previousState = setScannerState(SCANNER_STATE_COMMENT);
-        while (fScannerState == SCANNER_STATE_COMMENT) {
-            if (fEntityReader.lookingAtChar('-', false)) {
-                int nextEndOffset = fEntityReader.currentOffset();
-                int endOffset = 0;
-                fEntityReader.lookingAtChar('-', true);
-                int offset = fEntityReader.currentOffset();
-                int count = 1;
-                while (fEntityReader.lookingAtChar('-', true)) {
-                    count++;
-                    endOffset = nextEndOffset;
-                    nextEndOffset = offset;
-                    offset = fEntityReader.currentOffset();
-                }
-                if (count > 1) {
-                    if (fEntityReader.lookingAtChar('>', true)) {
-                        if (!sawDashDash && count > 2) {
-                            reportFatalXMLError(XMLMessages.MSG_DASH_DASH_IN_COMMENT,
-                                                XMLMessages.P15_DASH_DASH);
-                            sawDashDash = true;
-                        }
-                        fScannerMarkupDepth--;
-                        fEventHandler.callComment(fEntityReader.addString(commentOffset, endOffset - commentOffset));
-                        restoreScannerState(previousState);
-                        return;
-                    } else if (!sawDashDash) {
-                        reportFatalXMLError(XMLMessages.MSG_DASH_DASH_IN_COMMENT,
-                                            XMLMessages.P15_DASH_DASH);
-                        sawDashDash = true;
-                    }
-                }
-            } else {
-                if (!fEntityReader.lookingAtValidChar(true)) {
-                    int invChar = fEntityReader.scanInvalidChar();
-                    if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                        if (invChar >= 0) {
-                            reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_COMMENT,
-                                                XMLMessages.P15_INVALID_CHARACTER,
-                                                Integer.toHexString(invChar));
-                        }
-                    }
-                }
-            }
-        }
-        restoreScannerState(previousState);
-    }
-    //
-    // From the standard:
-    //
-    // [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
-    // [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
-    //
-    void scanPI(int piTarget) throws Exception
-    {
-        String piTargetString = fStringPool.toString(piTarget);
-        if (piTargetString.length() == 3 &&
-            (piTargetString.charAt(0) == 'X' || piTargetString.charAt(0) == 'x') &&
-            (piTargetString.charAt(1) == 'M' || piTargetString.charAt(1) == 'm') &&
-            (piTargetString.charAt(2) == 'L' || piTargetString.charAt(2) == 'l')) {
-            abortMarkup(XMLMessages.MSG_RESERVED_PITARGET,
-                        XMLMessages.P17_RESERVED_PITARGET);
-            return;
-        }
-        int prevState = setScannerState(SCANNER_STATE_PI);
-        int piDataOffset = -1;
-        int piDataLength = -1;
-        if (!fEntityReader.lookingAtSpace(true)) {
-            if (!fEntityReader.lookingAtChar('?', true) || !fEntityReader.lookingAtChar('>', true)) {
-                if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                    abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_IN_PI,
-                                XMLMessages.P16_WHITESPACE_REQUIRED);
-                    restoreScannerState(prevState);
-                }
-                return;
-            }
-            piDataLength = 0;
-        } else {
-            fEntityReader.skipPastSpaces();
-            piDataOffset = fEntityReader.currentOffset();
-            while (fScannerState == SCANNER_STATE_PI) {
-                while (fEntityReader.lookingAtChar('?', false)) {
-                    int offset = fEntityReader.currentOffset();
-                    fEntityReader.lookingAtChar('?', true);
-                    if (fEntityReader.lookingAtChar('>', true)) {
-                        piDataLength = offset - piDataOffset;
-                        break;
-                    }
-                }
-                if (piDataLength >= 0)
-                    break;
-                if (!fEntityReader.lookingAtValidChar(true)) {
-                    int invChar = fEntityReader.scanInvalidChar();
-                    if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
-                        if (invChar >= 0) {
-                            reportFatalXMLError(XMLMessages.MSG_INVALID_CHAR_IN_PI,
-                                                XMLMessages.P16_INVALID_CHARACTER,
-                                                Integer.toHexString(invChar));
-                        }
-                        skipPastEndOfCurrentMarkup();
-                        restoreScannerState(prevState);
-                    }
-                    return;
-                }
-            }
-        }
-        fScannerMarkupDepth--;
-        restoreScannerState(prevState);
-        int piData = piDataLength == 0 ?
-                     StringPool.EMPTY_STRING : fEntityReader.addString(piDataOffset, piDataLength);
-        fEventHandler.callProcessingInstruction(piTarget, piData);
-    }
-
-    /** Sets whether the parser preprocesses namespaces. */
-    public void setNamespacesEnabled(boolean enabled) {
-        fNamespacesEnabled = enabled;
-    }
-
-    /** Returns whether the parser processes namespaces. */
-    public boolean getNamespacesEnabled() {
-        return fNamespacesEnabled;
-    }
-
-    /** Sets whether the parser validates. */
-    public void setValidationEnabled(boolean enabled) {
-        fValidationEnabled = enabled;
-        if (fDTDScanner != null) {
-            fDTDScanner.setValidationEnabled(enabled);
-        }
-    }
-
-    /** Returns true if validation is turned on. */
-    public boolean getValidationEnabled() {
-        return fValidationEnabled;
-    }
-
-    // old EventHandler methods pushed back into scanner
-
-    /** Scans element type. */
-    private void scanElementType(XMLEntityHandler.EntityReader entityReader, 
-                                char fastchar, QName element) throws Exception {
-
-        if (!fNamespacesEnabled) {
-            element.clear();
-            element.localpart = entityReader.scanName(fastchar);
-            element.rawname = element.localpart;
-        } 
-        else {
-            entityReader.scanQName(fastchar, element);
-            if (entityReader.lookingAtChar(':', false)) {
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_TWO_COLONS_IN_QNAME,
-                                           XMLMessages.P5_INVALID_CHARACTER,
-                                           null,
-                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-                 entityReader.skipPastNmtoken(' ');
-            }
-        }
-
-        fEventHandler.element(element);
-
-    } // scanElementType(XMLEntityHandler.EntityReader,char,QName)
-
-    /** Scans expected element type. */
-    private boolean scanExpectedElementType(XMLEntityHandler.EntityReader entityReader, 
-                                           char fastchar, int elementType) 
-        throws Exception {
-
-        /***/
-        // REVISIT: Why aren't we using the 'element' parameter? -Ac
-        // REVISIT: I replaced the 'fCurrentElement' with 'element' parameter, still working, 
-        //          just wondering Why are we using CharArrayRange in the first place? -ericye
-        if (fCurrentElementCharArrayRange == null) {
-            fCurrentElementCharArrayRange = fStringPool.createCharArrayRange();
-        }
-        fStringPool.getCharArrayRange(elementType, fCurrentElementCharArrayRange);
-        return entityReader.scanExpectedName(fastchar, fCurrentElementCharArrayRange);
-        /***
-        entityReader.scanQName(fastchar, element);
-        return true;
-        /***/
-
-    } // scanExpectedElementType(XMLEntityHandler.EntityReader,char,QName)
-
-    /** Scans attribute name. */
-    private void scanAttributeName(XMLEntityHandler.EntityReader entityReader, 
-                                  QName element, QName attribute) 
-        throws Exception {
-
-        /***
-        // REVISIT: What's this check for?
-        if (!fSeenRootElement) {
-            fSeenRootElement = true;
-            rootElementSpecified(element);
-            fStringPool.resetShuffleCount();
-        }
-        /***/
-
-        if (!fNamespacesEnabled) {
-            attribute.clear();
-            attribute.localpart = entityReader.scanName('=');
-            attribute.rawname = attribute.localpart;
-        } 
-        else {
-            entityReader.scanQName('=', attribute);
-            if (entityReader.lookingAtChar(':', false)) {
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_TWO_COLONS_IN_QNAME,
-                                           XMLMessages.P5_INVALID_CHARACTER,
-                                           null,
-                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-                entityReader.skipPastNmtoken(' ');
-            }
-        }
-
-    } // scanAttributeName(XMLEntityHandler.EntityReader,QName,QName)
-
-    /** Scan doctype declaration. */
-    private void scanDoctypeDecl(boolean standalone) throws Exception {
-        
-        fScanningDTD = true;
-
-        /***
-        fScanningDTD = true;
-        fCheckedForSchema = true;
-        /***/
-        fSeenDoctypeDecl = true;
-        /***
-        fStandaloneReader = standalone ? fEntityHandler.getReaderId() : -1;
-        fDeclsAreExternal = false;
-        if (fDTDImporter == null) {
-            fDTDImporter = new DTDImporter(fStringPool, fErrorReporter, fEntityHandler, this);
-        } 
-        else {
-            fDTDImporter.reset(fStringPool);
-        }
-        fDTDImporter.initHandlers(fDTDHandler);
-        fDTDImporter.setValidating(fValidating);
-        fDTDImporter.setNamespacesEnabled(fNamespacesEnabled);
-        if (fDTDImporter.scanDoctypeDecl(standalone) && fValidating) {
-            // check declared elements
-            if (fWarningOnUndeclaredElements) {
-                // REVISIT: comment out because won't compile 
-                // checkDeclaredElements();
-            }
-
-            // check required notations
-            fEntityHandler.checkRequiredNotations();
-        }
-        fScanningDTD = false;
-        /***/
-        if (fDTDScanner == null) {
-            fDTDScanner = new XMLDTDScanner(fStringPool, fErrorReporter, fEntityHandler, new ChunkyCharArray(fStringPool));
-            fDTDScanner.setValidationEnabled(fValidationEnabled);
-            fDTDScanner.setNamespacesEnabled(fNamespacesEnabled);
-        }
-        else {
-            fDTDScanner.reset(fStringPool, new ChunkyCharArray(fStringPool));
-        }
-        fDTDScanner.setDTDHandler(fDTDHandler);
-        fDTDScanner.setGrammarResolver(fGrammarResolver);
-        // REVISIT: What about standalone?
-        if (fDTDScanner.scanDoctypeDecl()) {
-            if (fDTDScanner.getReadingExternalEntity()) {
-                fDTDScanner.scanDecls(true);
-            }
-            // REVISIT: What about validation and checking stuff?
-        }
-        //VC_NOTATION_DECLARED
-        if (fValidationEnabled) {
-            ((DefaultEntityHandler)fEntityHandler).checkRequiredNotations();
-        }
-        /***/
-        fScanningDTD = false;
-
-    } // scanDoctypeDecl(boolean)
-
-    /** Scan attribute value. */
-    private int scanAttValue(QName element, QName attribute) throws Exception {
-
-        //fAttrNameLocator = getLocatorImpl(fAttrNameLocator);
-        int attValue = scanAttValue(element, attribute, fValidationEnabled);
-        if (attValue == -1) {
-            return XMLDocumentScanner.RESULT_FAILURE;
-        }
-
-
-        /***
-        // REVISIT: This is validation related.
-        if (!fValidating && fAttDefCount == 0) {
-            int attType = fCDATASymbol;
-            if (fAttrListHandle == -1)
-                fAttrListHandle = fAttrList.startAttrList();
-            // REVISIT: Should this be localpart or rawname?
-            if (fAttrList.addAttr(attribute, attValue, attType, true, true) == -1) {
-                return XMLDocumentScanner.RESULT_DUPLICATE_ATTR;
-            }
-            return XMLDocumentScanner.RESULT_SUCCESS;
-        }
-        /****/
-
-        /****
-        // REVISIT: Validation. What should these be?
-        int attDefIndex = getAttDef(element, attribute);
-        if (attDefIndex == -1) {
-
-            if (fValidating) {
-                // REVISIT - cache the elem/attr tuple so that we only give
-                //  this error once for each unique occurrence
-                Object[] args = { fStringPool.toString(element.rawname),
-                                  fStringPool.toString(attribute.rawname) };
-                fErrorReporter.reportError(fAttrNameLocator,
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
-                                           XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
-                                           args,
-                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-            }
-
-            int attType = fCDATASymbol;
-            if (fAttrListHandle == -1) {
-                fAttrListHandle = fAttrList.startAttrList();
-            }
-            // REVISIT: Validation. What should the name be?
-            if (fAttrList.addAttr(attribute, attValue, attType, true, true) == -1) {
-                return XMLDocumentScanner.RESULT_DUPLICATE_ATTR;
-            }
-            return XMLDocumentScanner.RESULT_SUCCESS;
-        }
-        /****/
-
-        /****
-        int attType = getAttType(attDefIndex);
-        if (attType != fCDATASymbol) {
-            AttributeValidator av = getAttributeValidator(attDefIndex);
-            int enumHandle = getEnumeration(attDefIndex);
-            // REVISIT: Validation. What should these be?
-            attValue = av.normalize(element, attribute, 
-                                    attValue, attType, enumHandle);
-        }
-
-        if (fAttrListHandle == -1) {
-            fAttrListHandle = fAttrList.startAttrList();
-        }
-        // REVISIT: Validation. What should the name be?
-        if (fAttrList.addAttr(attribute, attValue, attType, true, true) == -1) {
-            return XMLDocumentScanner.RESULT_DUPLICATE_ATTR;
-        }
-        /***/
-
-        return XMLDocumentScanner.RESULT_SUCCESS;
-
-    } // scanAttValue(QName,QName):int
-
-    /** Returns true if the version number is valid. */
-    private boolean validVersionNum(String version) {
-        return XMLCharacterProperties.validVersionNum(version);
-    }
-
-    /** Returns true if the encoding name is valid. */
-    private boolean validEncName(String encoding) {
-        return XMLCharacterProperties.validEncName(encoding);
-    }
-
-} // class XMLDocumentScanner
diff --git a/src/org/apache/xerces/framework/XMLErrorReporter.java b/src/org/apache/xerces/framework/XMLErrorReporter.java
deleted file mode 100644
index 19a1926..0000000
--- a/src/org/apache/xerces/framework/XMLErrorReporter.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.framework;
-
-import org.xml.sax.Locator;
-
-/**
- * Error handling
- *
- * @version $Id$
- */
-public interface XMLErrorReporter {
-    //
-    // Constants
-    //
-
-    /** Warning type. */
-    public static final int ERRORTYPE_WARNING = 0;
-
-    /** Error type. */
-    public static final int ERRORTYPE_RECOVERABLE_ERROR = 1;
-
-    /** Fatal error type. */
-    public static final int ERRORTYPE_FATAL_ERROR = 2;
-
-    /**
-     * Get the default locator to use when reporting errors.
-     */
-    public Locator getLocator();
-
-    /**
-     * Report an error detected by a component of the XML parser.
-     * In a typical implementation of this interface, this method
-     * would call the error handler registered by the user with
-     * the appropriate error information.
-     *
-     * @param locator       Used to determine the location of the error.
-     * @param errorDomain   The error domain of the error.
-     * @param majorCode     The major key for the message text.
-     * @param minorCode     The minor key for the message text.
-     * @param args          The arguments to be used as replacement text
-     *                      in the message created.
-     * @param errorType     The type of error (ERRORTYPE_WARNING, ERRORTYPE_RECOVERABLE_ERROR, ERRORTYPE_FATAL_ERROR).
-     *
-     * @see #ERRORTYPE_WARNING
-     * @see #ERRORTYPE_RECOVERABLE_ERROR
-     * @see #ERRORTYPE_FATAL_ERROR
-     *
-     * @exception Exception Thrown if the parser should not continue
-     *                      to the error being handled.
-     */
-    public void reportError(Locator locator,
-                            String errorDomain,
-                            int majorCode,
-                            int minorCode,
-                            Object args[],
-                            int errorType) throws Exception;
-}
diff --git a/src/org/apache/xerces/framework/XMLParser.java b/src/org/apache/xerces/framework/XMLParser.java
deleted file mode 100644
index 4b13730..0000000
--- a/src/org/apache/xerces/framework/XMLParser.java
+++ /dev/null
@@ -1,1536 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.framework;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.Locale;
-
-import org.apache.xerces.readers.DefaultEntityHandler;
-import org.apache.xerces.readers.XMLDeclRecognizer;
-import org.apache.xerces.readers.XMLEntityHandler;
-import org.apache.xerces.readers.XMLEntityReaderFactory;
-import org.apache.xerces.utils.ChunkyCharArray;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.utils.XMLMessageProvider;
-import org.apache.xerces.utils.XMLMessages;
-import org.apache.xerces.utils.ImplementationMessages;
-import org.apache.xerces.validators.common.GrammarResolver;
-import org.apache.xerces.validators.common.GrammarResolverImpl;
-import org.apache.xerces.validators.common.XMLValidator;
-import org.apache.xerces.validators.datatype.DatatypeMessageProvider;
-import org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
-import org.apache.xerces.validators.schema.SchemaMessageProvider;
-
-import org.xml.sax.EntityResolver;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXNotRecognizedException;
-import org.xml.sax.SAXNotSupportedException;
-import org.xml.sax.SAXParseException;
-
-/**
- * This is the base class of all standard parsers.
- *
- * @version $Id$
- */
-public abstract class XMLParser 
-    implements XMLErrorReporter, XMLDocumentHandler.DTDHandler {
-
-    //
-    // Constants
-    //
-
-    // protected
-
-    /** SAX2 features prefix (http://xml.org/sax/features/). */
-    protected static final String SAX2_FEATURES_PREFIX = "http://xml.org/sax/features/";
-
-    /** SAX2 properties prefix (http://xml.org/sax/properties/). */
-    protected static final String SAX2_PROPERTIES_PREFIX = "http://xml.org/sax/properties/";
-
-    /** Xerces features prefix (http://apache.org/xml/features/). */
-    protected static final String XERCES_FEATURES_PREFIX = "http://apache.org/xml/features/";
-
-    /** Xerces properties prefix (http://apache.org/xml/properties/). */
-    protected static final String XERCES_PROPERTIES_PREFIX = "http://apache.org/xml/properties/";
-
-    // private
-
-    /** Features recognized by this parser. */
-    private static final String RECOGNIZED_FEATURES[] = {
-        // SAX2 core
-        "http://xml.org/sax/features/validation",
-        "http://xml.org/sax/features/external-general-entities",
-        "http://xml.org/sax/features/external-parameter-entities",
-        "http://xml.org/sax/features/namespaces",
-        // Xerces
-        "http://apache.org/xml/features/validation/schema",
-        "http://apache.org/xml/features/validation/dynamic",
-        "http://apache.org/xml/features/validation/default-attribute-values",
-        "http://apache.org/xml/features/validation/validate-content-models",
-        "http://apache.org/xml/features/validation/validate-datatypes",
-        "http://apache.org/xml/features/validation/warn-on-duplicate-attdef",
-        "http://apache.org/xml/features/validation/warn-on-undeclared-elemdef",
-        "http://apache.org/xml/features/allow-java-encodings",
-        "http://apache.org/xml/features/continue-after-fatal-error",
-        "http://apache.org/xml/features/nonvalidating/load-dtd-grammar"
-    };
-
-    /** Properties recognized by this parser. */
-    private static final String RECOGNIZED_PROPERTIES[] = {
-        // SAX2 core
-        "http://xml.org/sax/properties/xml-string",
-        // Xerces
-    };
-
-    // debugging
-
-    /** Set to true and recompile to print exception stack trace. */
-    private static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
-
-    //
-    // Data
-    //
-
-    protected GrammarResolver fGrammarResolver = null;
-
-    // state
-
-    protected boolean fParseInProgress = false;
-    private boolean fNeedReset = false;
-
-    // features
-
-    /** Continue after fatal error. */
-    private boolean fContinueAfterFatalError = false;
-
-    // properties
-
-    /** Error handler. */
-    private ErrorHandler fErrorHandler = null;
-
-    // other
-
-    private Locale fLocale = null;
-
-    // error information
-
-    private static XMLMessageProvider fgXMLMessages = new XMLMessages();
-    private static XMLMessageProvider fgImplementationMessages = new ImplementationMessages();
-    private static XMLMessageProvider fgSchemaMessages = new SchemaMessageProvider();
-    private static XMLMessageProvider fgDatatypeMessages= new DatatypeMessageProvider();
-
-    //
-    //
-    //
-    protected StringPool fStringPool = null;
-    protected XMLErrorReporter fErrorReporter = null;
-    protected DefaultEntityHandler fEntityHandler = null;
-    protected XMLDocumentScanner fScanner = null;
-    protected XMLValidator fValidator = null;
-
-    //
-    // Constructors
-    //
-
-    /**
-     * Constructor
-     */
-    protected XMLParser() {
-        fStringPool = new StringPool();
-        fErrorReporter = this;
-        fEntityHandler = new DefaultEntityHandler(fStringPool, fErrorReporter);
-        fScanner = new XMLDocumentScanner(fStringPool, fErrorReporter, fEntityHandler, new ChunkyCharArray(fStringPool));
-        fValidator = new XMLValidator(fStringPool, fErrorReporter, fEntityHandler, fScanner);
-        fGrammarResolver = new GrammarResolverImpl();
-        fScanner.setGrammarResolver(fGrammarResolver);
-        fValidator.setGrammarResolver(fGrammarResolver);
-        try {
-            //JR-defect 48 fix - turn on Namespaces
-            setNamespaces(true);
-        }
-        catch (Exception e) {
-            // ignore
-        }
-    }
-
-    /**
-     * Set char data processing preference and handlers.
-     */
-    protected void initHandlers(boolean sendCharDataAsCharArray,
-                                XMLDocumentHandler docHandler,
-                                XMLDocumentHandler.DTDHandler dtdHandler)
-    {
-        fValidator.initHandlers(sendCharDataAsCharArray, docHandler, dtdHandler);
-        fScanner.setDTDHandler(this);
-    }
-
-    //
-    // Public methods
-    //
-
-    // features and properties
-
-    /**
-     * Returns a list of features that this parser recognizes.
-     * This method will never return null; if no features are
-     * recognized, this method will return a zero length array.
-     *
-     * @see #isFeatureRecognized
-     * @see #setFeature
-     * @see #getFeature
-     */
-    public String[] getFeaturesRecognized() {
-        return RECOGNIZED_FEATURES;
-    }
-
-    /**
-     * Returns true if the specified feature is recognized.
-     *
-     * @see #getFeaturesRecognized
-     * @see #setFeature
-     * @see #getFeature
-     */
-    public boolean isFeatureRecognized(String featureId) {
-        String[] recognizedFeatures = getFeaturesRecognized();
-        for (int i = 0; i < recognizedFeatures.length; i++) {
-            if (featureId.equals(recognizedFeatures[i]))
-                return true;
-        }
-        return false;
-    }
-
-    /**
-     * Returns a list of properties that this parser recognizes.
-     * This method will never return null; if no properties are
-     * recognized, this method will return a zero length array.
-     *
-     * @see #isPropertyRecognized
-     * @see #setProperty
-     * @see #getProperty
-     */
-    public String[] getPropertiesRecognized() {
-        return RECOGNIZED_PROPERTIES;
-    }
-
-    /**
-     * Returns true if the specified property is recognized.
-     *
-     * @see #getPropertiesRecognized
-     * @see #setProperty
-     * @see #getProperty
-     */
-    public boolean isPropertyRecognized(String propertyId) {
-        String[] recognizedProperties = getPropertiesRecognized();
-        for (int i = 0; i < recognizedProperties.length; i++) {
-            if (propertyId.equals(recognizedProperties[i]))
-                return true;
-        }
-        return false;
-    }
-
-    // initialization
-
-    /**
-     * Setup for application-driven parsing.
-     *
-     * @param source the input source to be parsed.
-     * @see #parseSome
-     */
-    public boolean parseSomeSetup(InputSource source) throws Exception {
-        if (fNeedReset)
-            resetOrCopy();
-        fParseInProgress = true;
-        fNeedReset = true;
-        return fEntityHandler.startReadingFromDocument(source);
-    }
-
-    /**
-     * Application-driven parsing.
-     *
-     * @see #parseSomeSetup
-     */
-    public boolean parseSome() throws Exception {
-        if (!fScanner.parseSome(false)) {
-            fParseInProgress = false;
-            return false;
-        }
-        return true;
-    }
-
-    // resetting
-
-    /** Reset parser instance so that it can be reused. */
-    public void reset() throws Exception {
-        fGrammarResolver.clearGrammarResolver();
-        fStringPool.reset();
-        fEntityHandler.reset(fStringPool);
-        fScanner.reset(fStringPool, new ChunkyCharArray(fStringPool));
-        fValidator.reset(fStringPool);
-        fNeedReset = false;
-    }
-
-    // properties (the normal kind)
-
-    /**
-     * return the locator being used by the parser
-     *
-     * @return the parser's active locator
-     */
-    public final Locator getLocator() {
-        return fEntityHandler;
-    }
-
-    /**
-     * Set the reader factory.
-     */
-    public void setReaderFactory(XMLEntityReaderFactory readerFactory) {
-        fEntityHandler.setReaderFactory(readerFactory);
-    }
-
-    /**
-     * Adds a recognizer.
-     *
-     * @param recognizer The XML recognizer to add.
-     */
-    public void addRecognizer(XMLDeclRecognizer recognizer) {
-        fEntityHandler.addRecognizer(recognizer);
-    }
-
-    //
-    // Protected methods
-    //
-
-    // SAX2 core features
-
-    /**
-     * Sets whether the parser validates.
-     * <p>
-     * This method is the equivalent to the feature:
-     * <pre>
-     * http://xml.org/sax/features/validation
-     * </pre>
-     *
-     * @param validate True to validate; false to not validate.
-     *
-     * @see #getValidation
-     * @see #setFeature
-     */
-    protected void setValidation(boolean validate) 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        if (fParseInProgress) {
-            throw new SAXNotSupportedException("PAR004 Cannot setFeature(http://xml.org/sax/features/validation): parse is in progress.\n"+
-                                               "http://xml.org/sax/features/validation");
-        }
-        try {
-            // REVISIT: [Q] Should the scanner tell the validator that
-            //              validation is on? -Ac
-            fScanner.setValidationEnabled(validate);
-            fValidator.setValidationEnabled(validate);
-        }
-        catch (Exception ex) {
-            throw new SAXNotSupportedException(ex.getMessage());
-        }
-    }
-
-    /**
-     * Returns true if validation is turned on.
-     *
-     * @see #setValidation
-     */
-    protected boolean getValidation() 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        return fValidator.getValidationEnabled();
-    }
-
-    /**
-     * <b>Note: Currently, this parser always expands external general
-     * entities.</b> Setting this feature to false will throw a
-     * SAXNotSupportedException.
-     * <p>
-     * Sets whether external general entities are expanded.
-     * <p>
-     * This method is the equivalent to the feature:
-     * <pre>
-     * http://xml.org/sax/features/external-general-entities
-     * </pre>
-     *
-     * @param expand True to expand external general entities; false
-     *               to not expand.
-     *
-     * @see #getExternalGeneralEntities
-     * @see #setFeature
-     */
-    protected void setExternalGeneralEntities(boolean expand)
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        if (fParseInProgress) {
-            throw new SAXNotSupportedException("PAR004 Cannot setFeature(http://xml.org/sax/features/external-general-entities): parse is in progress.\n"+
-                                               "http://xml.org/sax/features/external-general-entities");
-        }
-        if (!expand) {
-            throw new SAXNotSupportedException("http://xml.org/sax/features/external-general-entities");
-        }
-    }
-
-    /**
-     * <b>Note: This feature is always true.</b>
-     * <p>
-     * Returns true if external general entities are expanded.
-     *
-     * @see #setExternalGeneralEntities
-     */
-    protected boolean getExternalGeneralEntities() 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        return true;
-    }
-
-    /**
-     * <b>Note: Currently, this parser always expands external parameter
-     * entities.</b> Setting this feature to false will throw a
-     * SAXNotSupportedException.
-     * <p>
-     * Sets whether external parameter entities are expanded.
-     * <p>
-     * This method is the equivalent to the feature:
-     * <pre>
-     * http://xml.org/sax/features/external-parameter-entities
-     * </pre>
-     *
-     * @param expand True to expand external parameter entities; false
-     *               to not expand.
-     *
-     * @see #getExternalParameterEntities
-     * @see #setFeature
-     */
-    protected void setExternalParameterEntities(boolean expand)
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        if (fParseInProgress) {
-            throw new SAXNotSupportedException("PAR004 Cannot setFeature(http://xml.org/sax/features/external-general-entities): parse is in progress.\n"+
-                                               "http://xml.org/sax/features/external-general-entities");
-        }
-        if (!expand) {
-            throw new SAXNotSupportedException("http://xml.org/sax/features/external-parameter-entities");
-        }
-    }
-
-    /**
-     * <b>Note: This feature is always true.</b>
-     * <p>
-     * Returns true if external parameter entities are expanded.
-     *
-     * @see #setExternalParameterEntities
-     */
-    protected boolean getExternalParameterEntities() 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        return true;
-    }
-
-    /**
-     * Sets whether the parser preprocesses namespaces.
-     * <p>
-     * This method is the equivalent to the feature:
-     * <pre>
-     * http://xml.org/sax/features/namespaces
-     * <pre>
-     *
-     * @param process True to process namespaces; false to not process.
-     *
-     * @see #getNamespaces
-     * @see #setFeature
-     */
-    protected void setNamespaces(boolean process) 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        if (fParseInProgress) {
-            throw new SAXNotSupportedException("PAR004 Cannot setFeature(http://xml.org/sax/features/namespaces): parse is in progress.\n"+
-                                               "http://xml.org/sax/features/namespaces");
-        }
-        fScanner.setNamespacesEnabled(process);
-        // REVISIT: [Q] Should the scanner tell the validator that namespace
-        //              processing is on? -Ac
-        fValidator.setNamespacesEnabled(process);
-    }
-
-    /**
-     * Returns true if the parser preprocesses namespaces.
-     *
-     * @see #setNamespaces
-     */
-    protected boolean getNamespaces() 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        return fValidator.getNamespacesEnabled();
-    }
-
-    // Xerces features
-
-    /**
-     * Allows the user to turn Schema support on/off.
-     * <p>
-     * This method is equivalent to the feature:
-     * <pre>
-     * http://apache.org/xml/features/validation/schema
-     * </pre>
-     *
-     * @param schema True to turn on Schema support; false to turn it off.
-     *
-     * @see #getValidationSchema
-     * @see #setFeature
-     */
-    protected void setValidationSchema(boolean schema) 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        if (fParseInProgress) {
-            // REVISIT: Localize message
-            throw new SAXNotSupportedException("http://apache.org/xml/features/validation/schema: parse is in progress");
-        }
-        fValidator.setSchemaValidationEnabled(schema);
-    }
-
-    /**
-     * Returns true if Schema support is turned on.
-     *
-     * @see #setValidationSchema
-     */
-    protected boolean getValidationSchema() 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        return fValidator.getSchemaValidationEnabled();
-    }
-
-    /**
-     * Allows the parser to validate a document only when it contains a
-     * grammar. Validation is turned on/off based on each document
-     * instance, automatically.
-     * <p>
-     * This method is the equivalent to the feature:
-     * <pre>
-     * http://apache.org/xml/features/validation/dynamic
-     * </pre>
-     *
-     * @param dynamic True to dynamically validate documents; false to
-     *                validate based on the validation feature.
-     *
-     * @see #getValidationDynamic
-     * @see #setFeature
-     */
-    protected void setValidationDynamic(boolean dynamic) 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        if (fParseInProgress) {
-            // REVISIT: Localize message
-            throw new SAXNotSupportedException("http://apache.org/xml/features/validation/dynamic: parse is in progress");
-        }
-        try {
-            fValidator.setDynamicValidationEnabled(dynamic);
-        }
-        catch (Exception ex) {
-            throw new SAXNotSupportedException(ex.getMessage());
-        }
-    }
-
-    /**
-     * Returns true if validation is based on whether a document
-     * contains a grammar.
-     *
-     * @see #setValidationDynamic
-     */
-    protected boolean getValidationDynamic() 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        return fValidator.getDynamicValidationEnabled();
-    }
-    /**
-     * Allows the parser to have the choice to load DTD grammar when 
-     * validation is off.
-     * <p>
-     * This method is the equivalent to the feature:
-     * <pre>
-     * http://apache.org/xml/features/nonvalidating/load-dtd-grammar
-     * </pre>
-     *
-     * @param loadDTDGrammar True to turn on the feature; false to
-     *                turn off the feature.
-     *
-     * @see #getLoadDTDGrammar
-     * @see #setFeature
-     */
-    protected void setLoadDTDGrammar(boolean loadDTDGrammar) 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        if (fParseInProgress) {
-            // REVISIT: Localize message
-            throw new SAXNotSupportedException("http://apache.org/xml/features/nonvalidating/load-dtd-grammar: parse is in progress");
-        }
-        try {
-            fValidator.setLoadDTDGrammar(loadDTDGrammar);
-        }
-        catch (Exception ex) {
-            throw new SAXNotSupportedException(ex.getMessage());
-        }
-    }
-
-    /**
-     * Returns true if load DTD grammar is turned on in the XMLValiator.
-     *
-     * @see #setLoadDTDGrammar
-     */
-    protected boolean getLoadDTDGrammar() 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        return fValidator.getLoadDTDGrammar();
-    }
-
-    /**
-     * Sets whether an error is emitted when an attribute is redefined
-     * in the grammar.
-     * <p>
-     * This method is the equivalent to the feature:
-     * <pre>
-     * http://apache.org/xml/features/validation/warn-on-duplicate-attdef
-     * </pre>
-     *
-     * @param warn True to warn; false to not warn.
-     *
-     * @see #getValidationWarnOnDuplicateAttdef
-     * @see #setFeature
-     */
-    protected void setValidationWarnOnDuplicateAttdef(boolean warn)
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        fValidator.setWarningOnDuplicateAttDef(warn);
-    }
-
-    /**
-     * Returns true if an error is emitted when an attribute is redefined
-     * in the grammar.
-     *
-     * @see #setValidationWarnOnDuplicateAttdef
-     */
-    protected boolean getValidationWarnOnDuplicateAttdef()
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        return fValidator.getWarningOnDuplicateAttDef();
-    }
-
-    /**
-     * Sets whether the parser emits an error when an element's content
-     * model references an element by name that is not declared in the
-     * grammar.
-     * <p>
-     * This method is the equivalent to the feature:
-     * <pre>
-     * http://apache.org/xml/features/validation/warn-on-undeclared-elemdef
-     * </pre>
-     *
-     * @param warn True to warn; false to not warn.
-     *
-     * @see #getValidationWarnOnUndeclaredElemdef
-     * @see #setFeature
-     */
-    protected void setValidationWarnOnUndeclaredElemdef(boolean warn)
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        fValidator.setWarningOnUndeclaredElements(warn);
-    }
-
-    /**
-     * Returns true if the parser emits an error when an undeclared
-     * element is referenced in the grammar.
-     *
-     * @see #setValidationWarnOnUndeclaredElemdef
-     */
-    protected boolean getValidationWarnOnUndeclaredElemdef()
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        return fValidator.getWarningOnUndeclaredElements();
-    }
-
-    /**
-     * Allows the use of Java encoding names in the XMLDecl and TextDecl
-     * lines in an XML document.
-     * <p>
-     * This method is the equivalent to the feature:
-     * <pre>
-     * http://apache.org/xml/features/allow-java-encodings
-     * </pre>
-     *
-     * @param allow True to allow Java encoding names; false to disallow.
-     *
-     * @see #getAllowJavaEncodings
-     * @see #setFeature
-     */
-    protected void setAllowJavaEncodings(boolean allow) 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        fEntityHandler.setAllowJavaEncodings(allow);
-    }
-
-    /**
-     * Returns true if Java encoding names are allowed in the XML document.
-     *
-     * @see #setAllowJavaEncodings
-     */
-    protected boolean getAllowJavaEncodings() 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        return fEntityHandler.getAllowJavaEncodings();
-    }
-
-    /**
-     * Allows the parser to continue after a fatal error. Normally, a
-     * fatal error would stop the parse.
-     * <p>
-     * This method is the equivalent to the feature:
-     * <pre>
-     * http://apache.org/xml/features/continue-after-fatal-error
-     * </pre>
-     *
-     * @param continueAfterFatalError True to continue; false to stop on
-     *                                fatal error.
-     *
-     * @see #getContinueAfterFatalError
-     * @see #setFeature
-     */
-    protected void setContinueAfterFatalError(boolean continueAfterFatalError)
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        fContinueAfterFatalError = continueAfterFatalError;
-    }
-
-    /**
-     * Returns true if the parser continues after a fatal error.
-     *
-     * @see #setContinueAfterFatalError
-     */
-    protected boolean getContinueAfterFatalError() 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        return fContinueAfterFatalError;
-    }
-
-    // SAX2 core properties
-
-    /**
-     * Set the separator to be used between the URI part of a name and the
-     * local part of a name when namespace processing is being performed
-     * (see the http://xml.org/sax/features/namespaces feature).  By default,
-     * the separator is a single space.
-     * <p>
-     * This property may not be set while a parse is in progress (throws a
-     * SAXNotSupportedException).
-     * <p>
-     * This method is the equivalent to the property:
-     * <pre>
-     * http://xml.org/sax/properties/namespace-sep
-     * </pre>
-     *
-     * @param separator The new namespace separator.
-     *
-     * @see #getNamespaceSep
-     * @see #setProperty
-     */
-    /***
-    protected void setNamespaceSep(String separator) 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        // REVISIT: Ask someone what it could possibly hurt to allow
-        //          the application to change this in mid-parse.
-        if (fParseInProgress) {
-            throw new SAXNotSupportedException("http://xml.org/sax/properties/namespace-sep: parse is in progress");
-        }
-        fNamespaceSep = separator;
-    }
-    /***/
-
-    /**
-     * Returns the namespace separator.
-     *
-     * @see #setNamespaceSep
-     */
-    /***
-    protected String getNamespaceSep() 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        return fNamespaceSep;
-    }
-    /***/
-
-    /**
-     * This method is the equivalent to the property:
-     * <pre>
-     * http://xml.org/sax/properties/xml-string
-     * </pre>
-     *
-     * @see #getProperty
-     */
-    protected String getXMLString() 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-        throw new SAXNotSupportedException("http://xml.org/sax/properties/xml-string");
-    }
-
-    // resetting
-
-    /**
-     * Reset or copy parser
-     * Allows parser instance reuse
-     */
-    protected void resetOrCopy() throws Exception {
-        fStringPool = new StringPool();
-        fEntityHandler.reset(fStringPool);
-        fScanner.reset(fStringPool, new ChunkyCharArray(fStringPool));
-        fValidator.resetOrCopy(fStringPool);
-        fNeedReset = false;
-        fGrammarResolver = new GrammarResolverImpl();
-        fScanner.setGrammarResolver(fGrammarResolver);
-        fValidator.setGrammarResolver(fGrammarResolver);
-        DatatypeValidatorFactoryImpl.getDatatypeRegistry().resetRegistry();
-    }
-
-    //
-    // Parser/XMLReader methods
-    //
-    // NOTE: This class does *not* implement the org.xml.sax.Parser
-    //       interface but it does share some common methods. -Ac
-
-    // handlers
-
-    /**
-     * Sets the resolver used to resolve external entities. The EntityResolver
-     * interface supports resolution of public and system identifiers.
-     *
-     * @param resolver The new entity resolver. Passing a null value will
-     *                 uninstall the currently installed resolver.
-     */
-    public void setEntityResolver(EntityResolver resolver) {
-        fEntityHandler.setEntityResolver(resolver);
-    }
-
-    /**
-     * Return the current entity resolver.
-     *
-     * @return The current entity resolver, or null if none
-     *         has been registered.
-     * @see #setEntityResolver
-     */
-    public EntityResolver getEntityResolver() {
-        return fEntityHandler.getEntityResolver();
-    }
-
-    /**
-     * Sets the error handler.
-     *
-     * @param handler The new error handler.
-     */
-    public void setErrorHandler(ErrorHandler handler) {
-        fErrorHandler = handler;
-    }
-
-    /**
-     * Return the current error handler.
-     *
-     * @return The current error handler, or null if none
-     *         has been registered.
-     * @see #setErrorHandler
-     */
-    public ErrorHandler getErrorHandler() {
-        return fErrorHandler;
-    }
-
-    // parsing
-
-    /**
-     * Parses the specified input source.
-     *
-     * @param source The input source.
-     *
-     * @exception org.xml.sax.SAXException Throws exception on SAX error.
-     * @exception java.io.IOException Throws exception on i/o error.
-     */
-    public void parse(InputSource source)
-        throws SAXException, IOException {
-
-        if (fParseInProgress) {
-            throw new org.xml.sax.SAXException("FWK005 parse may not be called while parsing."); // REVISIT - need to add new error message
-        }
-
-        try {
-            if (parseSomeSetup(source)) {
-                fScanner.parseSome(true);
-            }
-            fParseInProgress = false;
-        } catch (org.xml.sax.SAXException ex) {
-            fParseInProgress = false;
-            if (PRINT_EXCEPTION_STACK_TRACE)
-                ex.printStackTrace();
-            throw ex;
-        } catch (IOException ex) {
-            fParseInProgress = false;
-            if (PRINT_EXCEPTION_STACK_TRACE)
-                ex.printStackTrace();
-            throw ex;
-        } catch (Exception ex) {
-            fParseInProgress = false;
-            if (PRINT_EXCEPTION_STACK_TRACE)
-                ex.printStackTrace();
-            throw new org.xml.sax.SAXException(ex);
-        }
-
-    } // parse(InputSource)
-
-    /**
-     * Parses the input source specified by the given system identifier.
-     * <p>
-     * This method is equivalent to the following:
-     * <pre>
-     *     parse(new InputSource(systemId));
-     * </pre>
-     *
-     * @param source The input source.
-     *
-     * @exception org.xml.sax.SAXException Throws exception on SAX error.
-     * @exception java.io.IOException Throws exception on i/o error.
-     */
-    public void parse(String systemId)
-        throws SAXException, IOException {
-
-        InputSource source = new InputSource(systemId);
-        parse(source);
-        try {
-            Reader reader = source.getCharacterStream();
-            if (reader != null) {
-                reader.close();
-            }
-            else {
-                InputStream is = source.getByteStream();
-                if (is != null) {
-                    is.close();
-                }
-            }
-        }
-        catch (IOException e) {
-            // ignore
-        }
-
-    } // parse(String)
-
-    // locale
-
-    /**
-     * Set the locale to use for messages.
-     *
-     * @param locale The locale object to use for localization of messages.
-     *
-     * @exception SAXException An exception thrown if the parser does not
-     *                         support the specified locale.
-     *
-     * @see org.xml.sax.Parser
-     */
-    public void setLocale(Locale locale) throws SAXException {
-
-        if (fParseInProgress) {
-            throw new org.xml.sax.SAXException("FWK006 setLocale may not be called while parsing"); // REVISIT - need to add new error message
-        }
-
-        fLocale = locale;
-        fgXMLMessages.setLocale(locale);
-        fgImplementationMessages.setLocale(locale);
-
-    } // setLocale(Locale)
-
-    //
-    // XMLErrorReporter methods
-    //
-
-    /**
-     * Report an error.
-     *
-     * @param locator Location of error.
-     * @param errorDomain The error domain.
-     * @param majorCode The major code of the error.
-     * @param minorCode The minor code of the error.
-     * @param args Arguments for replacement text.
-     * @param errorType The type of the error.
-     *
-     * @exception Exception Thrown on error.
-     *
-     * @see XMLErrorReporter#ERRORTYPE_WARNING
-     * @see XMLErrorReporter#ERRORTYPE_FATAL_ERROR
-     */
-    public void reportError(Locator locator, String errorDomain,
-                            int majorCode, int minorCode, Object args[],
-                            int errorType) throws Exception {
-
-        // create the appropriate message
-        SAXParseException spe;
-        if (errorDomain.equals(XMLMessages.XML_DOMAIN)) {
-            spe = new SAXParseException(fgXMLMessages.createMessage(fLocale, majorCode, minorCode, args), locator);
-        }
-        else if (errorDomain.equals(XMLMessages.XMLNS_DOMAIN)) {
-            spe = new SAXParseException(fgXMLMessages.createMessage(fLocale, majorCode, minorCode, args), locator);
-        }
-        else if (errorDomain.equals(ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN)) {
-            spe = new SAXParseException(fgImplementationMessages.createMessage(fLocale, majorCode, minorCode, args), locator);
-        } else if (errorDomain.equals(SchemaMessageProvider.SCHEMA_DOMAIN)) {
-            spe = new SAXParseException(fgSchemaMessages.createMessage(fLocale, majorCode, minorCode, args), locator);
-        } else if (errorDomain.equals(DatatypeMessageProvider.DATATYPE_DOMAIN)) {
-            spe = new SAXParseException(fgDatatypeMessages.createMessage(fLocale, majorCode, minorCode, args), locator);
-        } else {
-            throw new RuntimeException("FWK007 Unknown error domain \"" + errorDomain + "\"."+"\n"+errorDomain);
-        }
-
-        // default error handling
-        if (fErrorHandler == null) {
-            if (errorType == XMLErrorReporter.ERRORTYPE_FATAL_ERROR &&
-                !fContinueAfterFatalError) {
-                throw spe;
-            }
-            return;
-        }
-
-        // make appropriate callback
-        if (errorType == XMLErrorReporter.ERRORTYPE_WARNING) {
-            fErrorHandler.warning(spe);
-        }
-        else if (errorType == XMLErrorReporter.ERRORTYPE_FATAL_ERROR) {
-            fErrorHandler.fatalError(spe);
-            if (!fContinueAfterFatalError) {
-                Object[] fatalArgs = { spe.getMessage() };
-                throw new SAXException(fgImplementationMessages.createMessage(fLocale, ImplementationMessages.FATAL_ERROR, 0, fatalArgs));
-            }
-        }
-        else {
-            fErrorHandler.error(spe);
-        }
-
-    } // reportError(Locator,String,int,int,Object[],int)
-
-    //
-    // XMLReader methods
-    //
-
-    /**
-     * Set the state of a feature.
-     *
-     * Set the state of any feature in a SAX2 parser.  The parser
-     * might not recognize the feature, and if it does recognize
-     * it, it might not be able to fulfill the request.
-     *
-     * @param featureId The unique identifier (URI) of the feature.
-     * @param state The requested state of the feature (true or false).
-     *
-     * @exception org.xml.sax.SAXNotRecognizedException If the
-     *            requested feature is not known.
-     * @exception org.xml.sax.SAXNotSupportedException If the
-     *            requested feature is known, but the requested
-     *            state is not supported.
-     * @exception org.xml.sax.SAXException If there is any other
-     *            problem fulfilling the request.
-     */
-    public void setFeature(String featureId, boolean state)
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-
-        //
-        // SAX2 Features
-        //
-
-        if (featureId.startsWith(SAX2_FEATURES_PREFIX)) {
-            String feature = featureId.substring(SAX2_FEATURES_PREFIX.length());
-            //
-            // http://xml.org/sax/features/validation
-            //   Validate (true) or don't validate (false).
-            //
-            if (feature.equals("validation")) {
-                setValidation(state);
-                return;
-            }
-            //
-            // http://xml.org/sax/features/external-general-entities
-            //   Expand external general entities (true) or don't expand (false).
-            //
-            if (feature.equals("external-general-entities")) {
-                setExternalGeneralEntities(state);
-                return;
-            }
-            //
-            // http://xml.org/sax/features/external-parameter-entities
-            //   Expand external parameter entities (true) or don't expand (false).
-            //
-            if (feature.equals("external-parameter-entities")) {
-                setExternalParameterEntities(state);
-                return;
-            }
-            //
-            // http://xml.org/sax/features/namespaces
-            //   Preprocess namespaces (true) or don't preprocess (false).  See also
-            //   the http://xml.org/sax/properties/namespace-sep property.
-            //
-            if (feature.equals("namespaces")) {
-                setNamespaces(state);
-                return;
-            }
-            //
-            // Not recognized
-            //
-        }
-
-        //
-        // Xerces Features
-        //
-
-        else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
-            String feature = featureId.substring(XERCES_FEATURES_PREFIX.length());
-            //
-            // http://apache.org/xml/features/validation/schema
-            //   Lets the user turn Schema validation support on/off.
-            //
-            if (feature.equals("validation/schema")) {
-                setValidationSchema(state);
-                return;
-            }
-            //
-            // http://apache.org/xml/features/validation/dynamic
-            //   Allows the parser to validate a document only when it
-            //   contains a grammar. Validation is turned on/off based
-            //   on each document instance, automatically.
-            //
-            if (feature.equals("validation/dynamic")) {
-                setValidationDynamic(state);
-                return;
-            }
-            //
-            // http://apache.org/xml/features/validation/default-attribute-values
-            //
-            if (feature.equals("validation/default-attribute-values")) {
-                // REVISIT
-                throw new SAXNotSupportedException(featureId);
-            }
-            //
-            // http://apache.org/xml/features/validation/default-attribute-values
-            //
-            if (feature.equals("validation/validate-content-models")) {
-                // REVISIT
-                throw new SAXNotSupportedException(featureId);
-            }
-            //
-            // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar
-            //
-            if (feature.equals("nonvalidating/load-dtd-grammar")) {
-                setLoadDTDGrammar(state);
-                return;
-            }
-
-            //
-            // http://apache.org/xml/features/validation/default-attribute-values
-            //
-            if (feature.equals("validation/validate-datatypes")) {
-                // REVISIT
-                throw new SAXNotSupportedException(featureId);
-            }
-            //
-            // http://apache.org/xml/features/validation/warn-on-duplicate-attdef
-            //   Emits an error when an attribute is redefined.
-            //
-            if (feature.equals("validation/warn-on-duplicate-attdef")) {
-                setValidationWarnOnDuplicateAttdef(state);
-                return;
-            }
-            //
-            // http://apache.org/xml/features/validation/warn-on-undeclared-elemdef
-            //   Emits an error when an element's content model
-            //   references an element, by name, that is not declared
-            //   in the grammar.
-            //
-            if (feature.equals("validation/warn-on-undeclared-elemdef")) {
-                setValidationWarnOnUndeclaredElemdef(state);
-                return;
-            }
-            //
-            // http://apache.org/xml/features/allow-java-encodings
-            //   Allows the use of Java encoding names in the XML
-            //   and TextDecl lines.
-            //
-            if (feature.equals("allow-java-encodings")) {
-                setAllowJavaEncodings(state);
-                return;
-            }
-            //
-            // http://apache.org/xml/features/continue-after-fatal-error
-            //   Allows the parser to continue after a fatal error.
-            //   Normally, a fatal error would stop the parse.
-            //
-            if (feature.equals("continue-after-fatal-error")) {
-                setContinueAfterFatalError(state);
-                return;
-            }
-            //
-            // Not recognized
-            //
-        }
-
-        //
-        // Not recognized
-        //
-
-        throw new SAXNotRecognizedException(featureId);
-
-    } // setFeature(String,boolean)
-
-    /**
-     * Query the state of a feature.
-     *
-     * Query the current state of any feature in a SAX2 parser.  The
-     * parser might not recognize the feature.
-     *
-     * @param featureId The unique identifier (URI) of the feature
-     *                  being set.
-     * @return The current state of the feature.
-     * @exception org.xml.sax.SAXNotRecognizedException If the
-     *            requested feature is not known.
-     * @exception org.xml.sax.SAXException If there is any other
-     *            problem fulfilling the request.
-     */
-    public boolean getFeature(String featureId) 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-
-        //
-        // SAX2 Features
-        //
-
-        if (featureId.startsWith(SAX2_FEATURES_PREFIX)) {
-            String feature = featureId.substring(SAX2_FEATURES_PREFIX.length());
-            //
-            // http://xml.org/sax/features/validation
-            //   Validate (true) or don't validate (false).
-            //
-            if (feature.equals("validation")) {
-                return getValidation();
-            }
-            //
-            // http://xml.org/sax/features/external-general-entities
-            //   Expand external general entities (true) or don't expand (false).
-            //
-            if (feature.equals("external-general-entities")) {
-                return getExternalGeneralEntities();
-            }
-            //
-            // http://xml.org/sax/features/external-parameter-entities
-            //   Expand external parameter entities (true) or don't expand (false).
-            //
-            if (feature.equals("external-parameter-entities")) {
-                return getExternalParameterEntities();
-            }
-            //
-            // http://xml.org/sax/features/namespaces
-            //   Preprocess namespaces (true) or don't preprocess (false).  See also
-            //   the http://xml.org/sax/properties/namespace-sep property.
-            //
-            if (feature.equals("namespaces")) {
-                return getNamespaces();
-            }
-            //
-            // Not recognized
-            //
-        }
-
-        //
-        // Xerces Features
-        //
-
-        else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
-            String feature = featureId.substring(XERCES_FEATURES_PREFIX.length());
-            //
-            // http://apache.org/xml/features/validation/schema
-            //   Lets the user turn Schema validation support on/off.
-            //
-            if (feature.equals("validation/schema")) {
-                return getValidationSchema();
-            }
-            //
-            // http://apache.org/xml/features/validation/dynamic
-            //   Allows the parser to validate a document only when it
-            //   contains a grammar. Validation is turned on/off based
-            //   on each document instance, automatically.
-            //
-            if (feature.equals("validation/dynamic")) {
-                return getValidationDynamic();
-            }
-            //
-            // http://apache.org/xml/features/validation/default-attribute-values
-            //
-            if (feature.equals("validation/default-attribute-values")) {
-                // REVISIT
-                throw new SAXNotRecognizedException(featureId);
-            }
-            //
-            // http://apache.org/xml/features/validation/validate-content-models
-            //
-            if (feature.equals("validation/validate-content-models")) {
-                // REVISIT
-                throw new SAXNotRecognizedException(featureId);
-            }
-            //
-            // http://apache.org/xml/features/validation/load-dtd-grammar
-            //
-            if (feature.equals("load-dtd-grammar")) {
-                return getLoadDTDGrammar();
-            }
-            //
-            // http://apache.org/xml/features/validation/validate-datatypes
-            //
-            if (feature.equals("validation/validate-datatypes")) {
-                // REVISIT
-                throw new SAXNotRecognizedException(featureId);
-            }
-            //
-            // http://apache.org/xml/features/validation/warn-on-duplicate-attdef
-            //   Emits an error when an attribute is redefined.
-            //
-            if (feature.equals("validation/warn-on-duplicate-attdef")) {
-                return getValidationWarnOnDuplicateAttdef();
-            }
-            //
-            // http://apache.org/xml/features/validation/warn-on-undeclared-elemdef
-            //   Emits an error when an element's content model
-            //   references an element, by name, that is not declared
-            //   in the grammar.
-            //
-            if (feature.equals("validation/warn-on-undeclared-elemdef")) {
-                return getValidationWarnOnUndeclaredElemdef();
-            }
-            //
-            // http://apache.org/xml/features/allow-java-encodings
-            //   Allows the use of Java encoding names in the XML
-            //   and TextDecl lines.
-            //
-            if (feature.equals("allow-java-encodings")) {
-                return getAllowJavaEncodings();
-            }
-            //
-            // http://apache.org/xml/features/continue-after-fatal-error
-            //   Allows the parser to continue after a fatal error.
-            //   Normally, a fatal error would stop the parse.
-            //
-            if (feature.equals("continue-after-fatal-error")) {
-                return getContinueAfterFatalError();
-            }
-            //
-            // Not recognized
-            //
-        }
-
-        //
-        // Not recognized
-        //
-
-        throw new SAXNotRecognizedException(featureId);
-
-    } // getFeature(String):boolean
-
-    /**
-     * Set the value of a property.
-     *
-     * Set the value of any property in a SAX2 parser.  The parser
-     * might not recognize the property, and if it does recognize
-     * it, it might not support the requested value.
-     *
-     * @param propertyId The unique identifier (URI) of the property
-     *                   being set.
-     * @param Object The value to which the property is being set.
-     * @exception org.xml.sax.SAXNotRecognizedException If the
-     *            requested property is not known.
-     * @exception org.xml.sax.SAXNotSupportedException If the
-     *            requested property is known, but the requested
-     *            value is not supported.
-     * @exception org.xml.sax.SAXException If there is any other
-     *            problem fulfilling the request.
-     */
-    public void setProperty(String propertyId, Object value)
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-
-        //
-        // SAX2 Properties
-        //
-
-        if (propertyId.startsWith(SAX2_PROPERTIES_PREFIX)) {
-            String property = propertyId.substring(SAX2_PROPERTIES_PREFIX.length());
-            //
-            // http://xml.org/sax/properties/namespace-sep
-            // Value type: String
-            // Access: read/write, pre-parse only
-            //   Set the separator to be used between the URI part of a name and the
-            //   local part of a name when namespace processing is being performed
-            //   (see the http://xml.org/sax/features/namespaces feature).  By
-            //   default, the separator is a single space.  This property may not be
-            //   set while a parse is in progress (throws a SAXNotSupportedException).
-            //
-            /***
-            if (property.equals("namespace-sep")) {
-                try {
-                    setNamespaceSep((String)value);
-                }
-                catch (ClassCastException e) {
-                    throw new SAXNotSupportedException(propertyId);
-                }
-                return;
-            }
-            /***/
-            
-            //
-            // http://xml.org/sax/properties/xml-string
-            // Value type: String
-            // Access: read-only
-            //   Get the literal string of characters associated with the current
-            //   event.  If the parser recognises and supports this property but is
-            //   not currently parsing text, it should return null (this is a good
-            //   way to check for availability before the parse begins).
-            //
-            if (property.equals("xml-string")) {
-                // REVISIT - we should probably ask xml-dev for a precise definition
-                // of what this is actually supposed to return, and in exactly which
-                // circumstances.
-                throw new SAXNotSupportedException(propertyId);
-            }
-            //
-            // Not recognized
-            //
-        }
-
-        //
-        // Xerces Properties
-        //
-
-        /*
-        else if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
-            //
-            // No properties defined yet that are common to all parsers.
-            //
-        }
-        */
-
-        //
-        // Not recognized
-        //
-
-        throw new SAXNotRecognizedException(propertyId);
-
-    } // setProperty(String,Object)
-
-    /**
-     * Query the value of a property.
-     *
-     * Return the current value of a property in a SAX2 parser.
-     * The parser might not recognize the property.
-     *
-     * @param propertyId The unique identifier (URI) of the property
-     *                   being set.
-     * @return The current value of the property.
-     * @exception org.xml.sax.SAXNotRecognizedException If the
-     *            requested property is not known.
-     * @exception org.xml.sax.SAXException If there is any other
-     *            problem fulfilling the request.
-     * @see org.xml.sax.XMLReader#getProperty
-     */
-    public Object getProperty(String propertyId) 
-        throws SAXNotRecognizedException, SAXNotSupportedException {
-
-        //
-        // SAX2 Properties
-        //
-
-        if (propertyId.startsWith(SAX2_PROPERTIES_PREFIX)) {
-            String property = propertyId.substring(SAX2_PROPERTIES_PREFIX.length());
-            //
-            // http://xml.org/sax/properties/namespace-sep
-            // Value type: String
-            // Access: read/write, pre-parse only
-            //   Set the separator to be used between the URI part of a name and the
-            //   local part of a name when namespace processing is being performed
-            //   (see the http://xml.org/sax/features/namespaces feature).  By
-            //   default, the separator is a single space.  This property may not be
-            //   set while a parse is in progress (throws a SAXNotSupportedException).
-            //
-            /***
-            if (property.equals("namespace-sep")) {
-                return getNamespaceSep();
-            }
-            /***/
-            //
-            // http://xml.org/sax/properties/xml-string
-            // Value type: String
-            // Access: read-only
-            //   Get the literal string of characters associated with the current
-            //   event.  If the parser recognises and supports this property but is
-            //   not currently parsing text, it should return null (this is a good
-            //   way to check for availability before the parse begins).
-            //
-            if (property.equals("xml-string")) {
-                return getXMLString();
-            }
-            //
-            // Not recognized
-            //
-        }
-
-        //
-        // Xerces Properties
-        //
-
-        /*
-        else if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
-            //
-            // No properties defined yet that are common to all parsers.
-            //
-        }
-        */
-
-        //
-        // Not recognized
-        //
-
-        throw new SAXNotRecognizedException(propertyId);
-
-    } // getProperty(String):Object
-
-}
diff --git a/src/org/apache/xerces/jaxp/DocumentBuilderFactoryImpl.java b/src/org/apache/xerces/jaxp/DocumentBuilderFactoryImpl.java
deleted file mode 100644
index 5e74952..0000000
--- a/src/org/apache/xerces/jaxp/DocumentBuilderFactoryImpl.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999-2000, Pierpaolo
- * Fumagalli <mailto:pier@betaversion.org>, http://www.apache.org.
- * For more information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.jaxp;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import org.xml.sax.SAXException;
-
-/**
- * The <code>DocumentBuilderFactory</code> implementation for the Apache
- * Xerces XML parser.
- *
- * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
- *         (Apache Software Foundation, Exoffice Technologies)
- * @version $Revision$ $Date$
- */
-public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory{
-
-    /**
-     * Create a new <code>DocumentBuilderFactoryImpl</code> instance.
-     */
-    public DocumentBuilderFactoryImpl() {
-        super();
-    }
-
-    /**
-     * Returns a new configured instance of type <code>DocumentBuilder</code>.
-     */
-    public DocumentBuilder newDocumentBuilder()
-    throws ParserConfigurationException {
-        return(new DocumentBuilderImpl(this.isNamespaceAware(),
-                                       this.isValidating()));
-    }
-}
diff --git a/src/org/apache/xerces/jaxp/DocumentBuilderImpl.java b/src/org/apache/xerces/jaxp/DocumentBuilderImpl.java
deleted file mode 100644
index b1218db..0000000
--- a/src/org/apache/xerces/jaxp/DocumentBuilderImpl.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999-2000, Pierpaolo
- * Fumagalli <mailto:pier@betaversion.org>, http://www.apache.org.
- * For more information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.jaxp;
-
-import java.io.IOException;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.ParserConfigurationException;
-import org.apache.xerces.parsers.DOMParser;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.w3c.dom.Document;
-
-/**
- * The <code>DocumentBuilder</code> implementation for the Apache Xerces XML
- * parser.
- *
- * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
- *         (Apache Software Foundation, Exoffice Technologies)
- * @version $Revision$ $Date$
- */
-public class DocumentBuilderImpl extends DocumentBuilder {
-
-    /** Wether this <code>SAXParserImpl</code> supports namespaces. */
-    private boolean namespaces=false;
-    /** Wether this <code>SAXParserImpl</code> supports validataion. */
-    private boolean validation=false;
-    /** The current Xerces SAX <code>Parser</code>. */
-    private DOMParser parser=null;
-
-    /** Deny no-argument construction. */
-    private DocumentBuilderImpl() {
-        super();
-    }
-
-    /**
-     * Create a new <code>SAXParserFactoryImpl</code> instance.
-     */
-    protected DocumentBuilderImpl(boolean namespaces, boolean validation)
-    throws ParserConfigurationException {
-        this();
-        DOMParser p=new DOMParser();
-        try {
-            p.setFeature("http://xml.org/sax/features/namespaces",namespaces);
-        } catch (SAXException e) {
-            throw new ParserConfigurationException("Cannot set namespace "+
-                "awareness to "+namespaces);
-        }
-        try {
-            p.setFeature("http://xml.org/sax/features/validation",validation);
-        } catch (SAXException e) {
-            throw new ParserConfigurationException("Cannot set validation to "+
-                validation);
-        }
-        this.namespaces=namespaces;
-        this.validation=validation;
-        this.parser=p;
-    }
-
-    /**
-     * Parses the content of the given <code>InputSource</code> and returns
-     * a <code>Document</code> object.
-     */
-    public Document parse(InputSource source)
-    throws SAXException, IOException, IllegalArgumentException {
-        if (source==null) throw new IllegalArgumentException();
-        this.parser.parse(source);
-        return(this.parser.getDocument());
-    }
-
-    /**
-     * Creates an new <code>Document</code> instance from the underlying DOM
-     * implementation.
-     */
-    public Document newDocument() {
-        return(new org.apache.xerces.dom.DocumentImpl());
-    }
-
-    /**
-     * Returns whether or not this parser supports XML namespaces.
-     */
-    public boolean isNamespaceAware() {
-        return(this.namespaces);
-    }
-
-    /**
-     * Returns whether or not this parser supports validating XML content.
-     */
-    public boolean isValidating() {
-        return(this.validation);
-    }
-
-    /**
-     * Specifies the <code>EntityResolver</code> to be used by this
-     * <code>DocumentBuilderImpl</code>.
-     */
-    public void setEntityResolver(EntityResolver er) {
-        this.parser.setEntityResolver(er);
-    }
-
-    /**
-     * Specifies the <code>ErrorHandler</code> to be used by this
-     * <code>DocumentBuilderImpl</code>.
-     */
-    public void setErrorHandler(ErrorHandler eh) {
-        this.parser.setErrorHandler(eh);
-    }
-}
-
diff --git a/src/org/apache/xerces/jaxp/Makefile b/src/org/apache/xerces/jaxp/Makefile
deleted file mode 100644
index 024e2d8..0000000
--- a/src/org/apache/xerces/jaxp/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# Makefile for directory ./org/apache/xerces/jaxp
-
-TARGETS = DocumentBuilderFactoryImpl.class\
-        DocumentBuilderImpl.class\
-        SAXParserFactoryImpl.class\
-        SAXParserImpl.class
-
-DIRS =
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xerces/jaxp/SAXParserFactoryImpl.java b/src/org/apache/xerces/jaxp/SAXParserFactoryImpl.java
deleted file mode 100644
index cb4f13c..0000000
--- a/src/org/apache/xerces/jaxp/SAXParserFactoryImpl.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999-2000, Pierpaolo
- * Fumagalli <mailto:pier@betaversion.org>, http://www.apache.org.
- * For more information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.jaxp;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import org.xml.sax.SAXException;
-
-/**
- * The <code>SAXParserFactory</code> implementation for the Apache Xerces
- * XML parser.
- *
- * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
- *         (Apache Software Foundation, Exoffice Technologies)
- * @version $Revision$ $Date$
- */
-public class SAXParserFactoryImpl extends SAXParserFactory {
-
-    /**
-     * Create a new <code>SAXParserFactoryImpl</code> instance.
-     */
-    public SAXParserFactoryImpl() {
-        super();
-    }
-
-    /**
-     * Returns a new configured instance of type <code>SAXParser</code>.
-     */
-    public SAXParser newSAXParser()
-    throws ParserConfigurationException {
-        return(new SAXParserImpl(this.isNamespaceAware(),this.isValidating()));
-    }
-}
diff --git a/src/org/apache/xerces/jaxp/SAXParserImpl.java b/src/org/apache/xerces/jaxp/SAXParserImpl.java
deleted file mode 100644
index bbd7448..0000000
--- a/src/org/apache/xerces/jaxp/SAXParserImpl.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999-2000, Pierpaolo
- * Fumagalli <mailto:pier@betaversion.org>, http://www.apache.org.
- * For more information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.jaxp;
-
-import java.io.File;
-import java.io.InputStream;
-import java.io.IOException;
-import javax.xml.parsers.ParserConfigurationException;
-import org.apache.xerces.parsers.SAXParser;
-import org.xml.sax.HandlerBase;
-import org.xml.sax.InputSource;
-import org.xml.sax.Parser;
-import org.xml.sax.SAXException;
-
-/**
- * The <code>SAXParser</code> implementation for the Apache Xerces XML parser.
- *
- * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
- *         (Apache Software Foundation, Exoffice Technologies)
- * @version $Revision$ $Date$
- */
-public class SAXParserImpl extends javax.xml.parsers.SAXParser {
-
-    /** Wether this <code>SAXParserImpl</code> supports namespaces. */
-    private boolean namespaces=false;
-    /** Wether this <code>SAXParserImpl</code> supports validataion. */
-    private boolean validation=false;
-    /** The current Xerces SAX <code>Parser</code>. */
-    private Parser parser=null;
-
-    /** Deny no-argument construction. */
-    private SAXParserImpl() {
-        super();
-    }
-
-    /**
-     * Create a new <code>SAXParserFactoryImpl</code> instance.
-     */
-    protected SAXParserImpl(boolean namespaces, boolean validation)
-    throws ParserConfigurationException {
-        this();
-        SAXParser p=new SAXParser();
-        try {
-            p.setFeature("http://xml.org/sax/features/namespaces",namespaces);
-        } catch (SAXException e) {
-            throw new ParserConfigurationException("Cannot set namespace "+
-                "awareness to "+namespaces);
-        }
-        try {
-            p.setFeature("http://xml.org/sax/features/validation",validation);
-        } catch (SAXException e) {
-            throw new ParserConfigurationException("Cannot set validation to "+
-                validation);
-        }
-        this.namespaces=namespaces;
-        this.validation=validation;
-        this.parser=p;
-    }
-
-    /**
-     * Returns the underlying <code>Parser</code> object which is wrapped by
-     * this <code>SAXParserImpl</code> implementation.
-     */
-    public Parser getParser() {
-        return(this.parser);
-    }
-
-    /**
-     * Returns whether or not this parser supports XML namespaces.
-     */
-    public boolean isNamespaceAware() {
-        return(this.namespaces);
-    }
-
-    /**
-     * Returns whether or not this parser supports validating XML content.
-     */
-    public boolean isValidating() {
-        return(this.validation);
-    }
-}
diff --git a/src/org/apache/xerces/msg/DatatypeMessages.java b/src/org/apache/xerces/msg/DatatypeMessages.java
deleted file mode 100644
index ad40add..0000000
--- a/src/org/apache/xerces/msg/DatatypeMessages.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.msg;
-
-import java.util.ListResourceBundle;
-
-/**
- * This file contains error and warning messages for the schema datatype validator
- * The messages are arranged in key and value tuples in a ListResourceBundle.
- *
- *
- * @version
- */
-public class DatatypeMessages extends ListResourceBundle {
-    /** The list resource bundle contents. */
-    public static final Object CONTENTS[][] = {
-// Internal message formatter messages
-        { "BadMajorCode", "The majorCode parameter to createMessage was out of bounds." },
-        { "FormatFailed", "An internal error occurred while formatting the following message:\n  " },
-        { "NotBoolean", "{0} is not a boolean." },
-        { "NotDecimal", "{0} is not a decimal." },
-        { "FacetsInconsistent", "Facets are inconsistent with base type." },
-        { "IllegalFacetValue", "Illegal value {0} for facet {1}." },
-        { "IllegalDecimalFacet", "Illegal Facet for decimal type." },
-        { "UnknownFacet", "Unknown Facet: {0}." },
-        { "InvalidEnumValue", "Invalid value for Enum constant: {0}." },
-        { "OutOfBounds", "{0} is out of bounds:[ {1} {3} X  {4} {2} ]." },
-        { "NotAnEnumValue", "{0} is not one of the specified enum values." },
-        { "NotInteger", "{0} is not an integer." },
-        { "IllegalIntegerFacet", "Illegal Facet for Integer type." },
-        { "NotReal", "{0} is not a double." },
-        { "IllegalRealFacet", "Illegal Facet for Real type." },
-        { "ScaleLargerThanPrecision", "Scale Facet must be less than or equal to Precision Facet" },
-        { "PrecisionExceeded", "{0} has exceeded the precision Facet {1}"},
-        { "ScaleExceeded", "{0} has execeed the scale Facet {1}"},
-        { "NotFloat", "{0} is not a float." },
-    };
-
-    /** Returns the list resource bundle contents. */
-    public Object[][] getContents() {
-        return CONTENTS;
-    }
-}
diff --git a/src/org/apache/xerces/msg/ExceptionMessages.java b/src/org/apache/xerces/msg/ExceptionMessages.java
deleted file mode 100644
index 5195fe6..0000000
--- a/src/org/apache/xerces/msg/ExceptionMessages.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.msg;
-
-import java.util.ListResourceBundle;
-
-/**
- * This file contains error and warning messages to be localized
- * The messages are arranged in key and value tuples in a ListResourceBundle.
- *
- * @version $Id$
- */
-public class ExceptionMessages extends ListResourceBundle {
-    /** The list resource bundle contents. */
-    public static final Object CONTENTS[][] = {
-    
-    // org.apache.xerces.msg.ExceptionMessageLocalizer
-    { "FMT001", "Message Formatting Error." },
-    
-
-    // org.apache.html
-
-    { "HTM001", "State error: startDocument fired twice on one builder." },
-    { "HTM002", "State error: document never started or missing document element." },
-    { "HTM003", "State error: document ended before end of document element." },
-    { "HTM004", "Argument ''tagName'' is null." },
-    { "HTM005", "State error: Document.getDocumentElement returns null." },
-    { "HTM006", "State error: startElement called after end of document element." },
-    { "HTM007", "State error: endElement called with no current node." },
-    { "HTM008", "State error: mismatch in closing tag name {0}" },
-    { "HTM009", "State error: character data found outside of root element." },
-    { "HTM010", "State error: character data found outside of root element." },
-    { "HTM011", "Argument ''topLevel'' is null." },
-    { "HTM012", "Argument ''index'' is negative." },
-    { "HTM013", "Argument ''name'' is null." },
-    { "HTM014", "Argument ''title'' is null." },
-    { "HTM015", "Tag ''{0}'' associated with an Element class that failed to construct." },
-    { "HTM016", "Argument ''caption'' is not an element of type <CAPTION>." },
-    { "HTM017", "Argument ''tHead'' is not an element of type <THEAD>." },
-    { "HTM018", "Argument ''tFoot'' is not an element of type <TFOOT>." },
-    { "HTM019", "OpenXML Error: Could not find class {0} implementing HTML element {1}" },
-
-    // org.apache.xml.serialize
-
-    { "SER001", "Argument ''output'' is null." },
-    { "SER002", "No writer supplied for serializer" },
-    { "SER003", "The resource [{0}] could not be found." },
-    { "SER004", "The resource [{0}] could not load: {1}" },
-    { "SER005", "The method ''{0}'' is not supported by this factory" },
-
-    // org.apache.xerces.dom
-
-    { "DOM001", "Modification not allowed" },
-    { "DOM002", "Illegal character" },
-    { "DOM003", "Namespace error" },
-    { "DOM004", "Index out of bounds" },
-    { "DOM005", "Wrong document" },
-    { "DOM006", "Hierarchy request error" },
-    { "DOM007", "Not supported" },
-    { "DOM008", "Not found" },
-    { "DOM009", "Attribute already in use" },
-    { "DOM010", "Unspecified event type" },
-    { "DOM011", "Invalid state" },
-    { "DOM012", "Invalid node type" },
-    { "DOM013", "Bad boundary points" },
-
-    // org.apache.xerces.framework
-    { "FWK001", "{0}] scannerState: {1}" },
-    { "FWK002", "{0}] popElementType: fElementDepth-- == 0." },
-    { "FWK003", "TrailingMiscDispatcher.endOfInput moreToFollow" },
-    { "FWK004", "cannot happen: {0}" },
-    { "FWK005", "parse may not be called while parsing." },
-    { "FWK006", "setLocale may not be called while parsing." },
-    { "FWK007", "Unknown error domain \"{0}\"." },
-    { "FWK008", "Element stack underflow." },
-        
-    // org.apache.xerces.parsers
-    { "PAR001", "Fatal error constructing DOMParser." },
-    { "PAR002", "Class, \"{0}\", is not of type org.w3c.dom" },
-    { "PAR003", "Class, \"{0}\", not found." },
-    { "PAR004", "Cannot setFeature({0}): parse is in progress." },
-    { "PAR005", "Property, \"{0}\" is read-only." },
-    { "PAR006", "Property value must be of type java.lang.String." },
-    { "PAR007", "Current element node cannot be queried when node expansion is deferred." },
-    { "PAR008", "Fatal error getting document factory." },
-    { "PAR009", "Fatal error reading expansion mode." },
-    { "PAR010", "Can''t copy node type, {0} ({1})." },
-    { "PAR011", "Feature {0} not supported during parse." },
-    { "PAR012", "For propertyId \"{0}\", the value \""+
-                "{1}\" cannot be cast to {2}." },
-    { "PAR013", "Property \"{0}\" is read only." },
-    { "PAR014", "Cannot getProperty(\"{0}\". No DOM tree exists." },
-    { "PAR015", "startEntityReference(): ENTITYTYPE_UNPARSED" },
-    { "PAR016", "endEntityReference(): ENTITYTYPE_UNPARSED" },
-    { "PAR017", "cannot happen: {0}" },
-    
-    // org.apache.xerces.readers
-
-    { "RDR001", "untested" },
-    { "RDR002", "cannot happen" },
-            
-    //org.apache.xerces.utils
-    { "UTL001", "untested" },
-    { "UTL002", "cannot happen" },
-
-    //org.apache.xerces.validators
-
-    { "VAL001", "Element stack underflow" },
-    { "VAL002", "getValidatorForAttType ({0})" },
-    { "VAL003",  "cannot happen" }
-
-        
-    };
-    /** Returns the list resource bundle contents. */
-
-    public Object[][] getContents() {
-        return CONTENTS;
-    }
-}
diff --git a/src/org/apache/xerces/msg/ExceptionMessagesLocalizer.java b/src/org/apache/xerces/msg/ExceptionMessagesLocalizer.java
deleted file mode 100644
index 3daf192..0000000
--- a/src/org/apache/xerces/msg/ExceptionMessagesLocalizer.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.msg;
-
-import java.util.Locale;
-import java.util.ListResourceBundle;
-import java.util.ResourceBundle;
-import java.util.StringTokenizer;
-
-
-public class ExceptionMessagesLocalizer {
-    
-    static final String FMT001 = "FMT001";
-    
-    
-    //REVIST: Do we make this an object and have a set, getLocale,
-    // and cache the bundle?
-    
-    /** This method returns the localized message */
-    public static String localizeMessage(String string, Locale locale) {
-        
-        ResourceBundle fResourceBundle = null;
-        if (locale != null)
-            fResourceBundle = ListResourceBundle.getBundle("org.apache.xerces.msg.ExceptionMessages", locale);
-        if (fResourceBundle == null || locale == null)
-            fResourceBundle = ListResourceBundle.getBundle("org.apache.xerces.msg.ExceptionMessages");
-        
-        int keyIndex = string.indexOf(' ');
-        String key = string.substring(0, keyIndex);
-        // newline index
-        int nlIndex = string.indexOf('\n');
-        if (nlIndex == 0 || key == null || key.equals("")) return null; // REVIST: should never happen
- 
-        String msg = fResourceBundle.getString(key);
-        if (nlIndex < 0) {
-            return msg;
-        }
-       
-        StringTokenizer st = new StringTokenizer(string.substring(nlIndex+1), "\t");
-        int count = st.countTokens();
-        String [] args = new String[count];
-        for(int i=0; i < count; i++) {
-            args[i] = st.nextToken();
-        }
-        
-        if (args != null) {
-            try {
-                msg = java.text.MessageFormat.format(msg, args);
-            } catch (Exception e) {
-                msg = fResourceBundle.getString(FMT001)+ ": " + msg;
-            }
-        } 
-        return msg;
-    }
-    
-}
\ No newline at end of file
diff --git a/src/org/apache/xerces/msg/ImplementationMessages.java b/src/org/apache/xerces/msg/ImplementationMessages.java
deleted file mode 100644
index 0289fb6..0000000
--- a/src/org/apache/xerces/msg/ImplementationMessages.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.msg;
-
-/**
- * <p>
- * This file contains error and warning messages used by the Apache
- * Xerces parser. The messages are arranged in key and value
- * tuples in a ListResourceBundle.
- *
- * @version
- */
-public class ImplementationMessages
-    extends java.util.ListResourceBundle
-    {
-    /** The list resource bundle contents. */
-    public static final Object CONTENTS[][] = {
-// Internal message formatter messages
-        { "BadMajorCode", "The majorCode parameter to createMessage was out of bounds." },
-        { "FormatFailed", "An internal error occurred while formatting the following message:\n  " },
-// Xerces implementation defined errors
-        { "ENC4", "Invalid UTF-8 code. (byte: 0x{0})" },
-        { "ENC5", "Invalid UTF-8 code. (bytes: 0x{0} 0x{1})" },
-        { "ENC6", "Invalid UTF-8 code. (bytes: 0x{0} 0x{1} 0x{2})" },
-        { "ENC7", "Invalid UTF-8 code. (bytes: 0x{0} 0x{1} 0x{2} 0x{3})" },
-        { "FileNotFound", "File \"{0}\" not found." },
-        { "VAL_BST", "Invalid ContentSpecNode.NODE_XXX value for binary op CMNode" },
-        { "VAL_CMSI", "Invalid CMStateSet bit index" },
-        { "VAL_CST", "Unknown ContentSpecNode.NODE_XXX value" },
-        { "VAL_LST", "Invalid ContentSpecNode.NODE_XXX value for leaf CMNode" },
-        { "VAL_NIICM", "Only * unary ops should be in the internal content model tree"},
-        { "VAL_NPCD", "PCData node found in non-mixed model content" },
-        { "VAL_UST", "Invalid ContentSpecNode.NODE_XXX value for unary op CMNode" },
-        { "VAL_WCGHI", "The input to whatCanGoHere() is inconsistent" },
-        { "INT_DCN", "Internal Error: dataChunk == NULL" },
-        { "INT_PCN", "Internal Error: fPreviousChunk == NULL" },
-        { "FatalError", "Stopping after fatal error: {0}" },
-    };
-
-    /** Returns the list resource bundle contents. */
-    public Object[][] getContents() {
-        return CONTENTS;
-    }
-
-} // class Message
diff --git a/src/org/apache/xerces/msg/Makefile b/src/org/apache/xerces/msg/Makefile
deleted file mode 100644
index 221935e..0000000
--- a/src/org/apache/xerces/msg/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# Makefile for directory ./org/apache/xerces/msg
-
-TARGETS=\
-	DatatypeMessages.class\
-	ExceptionMessages.class \
-	SchemaMessages.class\
-	XMLMessages.class\
-	ImplementationMessages.class
-
-DIRS =
-
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xerces/msg/SchemaMessages.java b/src/org/apache/xerces/msg/SchemaMessages.java
deleted file mode 100644
index 9e409ea..0000000
--- a/src/org/apache/xerces/msg/SchemaMessages.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.msg;
-
-import java.util.ListResourceBundle;
-
-/**
- * This file contains error and warning messages for the Schema validator
- * The messages are arranged in key and value tuples in a ListResourceBundle.
- *
- * @version $Id$
- */
-public class SchemaMessages extends ListResourceBundle {
-    /** The list resource bundle contents. */
-    public static final Object CONTENTS[][] = {
-// Internal message formatter messages
-        { "BadMajorCode", "The majorCode parameter to createMessage was out of bounds." },
-        { "FormatFailed", "An internal error occurred while formatting the following message:\n  " },
-        { "NoValidatorFor", "No validator for datatype {0}" },
-        { "IncorrectDatatype", "Incorrect datatype: {0}" },
-        { "NotADatatype", "{0} is not a datatype." },
-        { "TextOnlyContentWithType", "The content attribute must be 'textOnly' if you specify a type attribute." },
-        { "FeatureUnsupported", "{0} is unsupported" },
-        { "NestedOnlyInElemOnly", "Nested Element decls only allowed in elementOnly content" },
-        { "EltRefOnlyInMixedElemOnly", "Element references only allowed in mixed or elementOnly content"},
-        { "OnlyInEltContent", "{0} only allowed in elementOnly content."},
-        { "OrderIsAll", "{0} not allowed if the order is all."},
-        { "DatatypeWithType", "Datatype qualifiers can only be used if you specify a type attribute."},
-        { "DatatypeQualUnsupported", "The datatype qualifier {0} is not supported."},
-        { "GroupContentRestricted", "Error: {0} content must be one of element, group, modelGroupRef.  Saw {1}"},
-        { "UnknownBaseDatatype", "Unknown base type {0} for type {1}." },
-        { "OneOfTypeRefArchRef", "Can only have one of type and ref attributes."},
-        { "NoContentForRef", "Cannot have child content for an element declaration that has a ref attribute" },
-        { "IncorrectDefaultType", "Incorrect type for {0}'s default value: {1}" },
-        { "IllegalAttContent", "Illegal content {0} in attribute group" },
-        { "ValueNotInteger", "Value of {0} is not an integer." },
-        { "DatatypeError", "Datatype error: {0}." },
-		{ "TypeAlreadySet", "The type of the element has already been declared." },
-		{ "GenericError", "Schema error: {0}." },
-		{ "UnexpectedError", "UnexpectedError" },
-   };
-    
-    /** Returns the list resource bundle contents. */
-    public Object[][] getContents() {
-        return CONTENTS;
-    }
-
-}
diff --git a/src/org/apache/xerces/msg/XMLMessages.java b/src/org/apache/xerces/msg/XMLMessages.java
deleted file mode 100644
index b28d394..0000000
--- a/src/org/apache/xerces/msg/XMLMessages.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.msg;
-
-import java.util.ListResourceBundle;
-
-/**
- * This file contains error and warning messages related to XML
- * The messages are arranged in key and value tuples in a ListResourceBundle.
- *
- * @version
- */
-public class XMLMessages extends ListResourceBundle {
-    /** The list resource bundle contents. */
-    public static final Object CONTENTS[][] = {
-// Internal message formatter messages
-        { "BadMajorCode", "The majorCode parameter to createMessage was out of bounds." },
-        { "FormatFailed", "An internal error occurred while formatting the following message:\n  " },
-// Document messages
-    // 2.1 Well-Formed XML Documents
-        { "RootElementRequired", "The root element is required in a well-formed document." },
-    // 2.2 Characters
-        { "InvalidCharInCDSect", "An invalid XML character (Unicode: 0x{0}) was found in the CDATA section." },
-        { "InvalidCharInContent", "An invalid XML character (Unicode: 0x{0}) was found in the element content of the document." },
-        { "TwoColonsInQName", "An invalid second ':' was found in the element type or attribute name." },
-        { "InvalidCharInMisc", "An invalid XML character (Unicode: 0x{0}) was found in markup after the end of the element content." },
-        { "InvalidCharInProlog", "An invalid XML character (Unicode: 0x{0}) was found in the prolog of the document." },
-        { "InvalidCharInXMLDecl", "An invalid XML character (Unicode: 0x{0}) was found in the XML declaration." },
-    // 2.4 Character Data and Markup
-        { "CDEndInContent", "The character sequence \"]]>\" must not appear in content unless used to mark the end of a CDATA section." },
-    // 2.7 CDATA Sections
-        { "CDSectUnterminated", "The CDATA section must end with \"]]>\"." },
-    // 2.8 Prolog and Document Type Declaration
-        { "XMLDeclMustBeFirst", "The XML declaration may only appear at the very beginning of the document." },
-        { "EqRequiredInXMLDecl", "The ''='' character must follow \"{0}\" in the XML declaration." },
-        { "QuoteRequiredInXMLDecl",  "The value following \"{0}\" in the XML declaration must be a quoted string." },
-        { "XMLDeclUnterminated", "The XML declaration must end with \"?>\"." },
-        { "VersionInfoRequired", "The version is required in the XML declaration." },
-        { "MarkupNotRecognizedInProlog", "The markup in the document preceding the root element must be well-formed." },
-        { "MarkupNotRecognizedInMisc", "The markup in the document following the root element must be well-formed." },
-    // 2.9 Standalone Document Declaration
-        { "SDDeclInvalid", "The standalone document declaration value must be \"yes\" or \"no\", not \"{0}\"." },
-    // 2.12 Language Identification
-        { "XMLLangInvalid", "The xml:lang attribute value \"{0}\" is an invalid language identifier." },
-    // 3. Logical Structures
-        { "ETagRequired", "The element type \"{0}\" must be terminated by the matching end-tag \"</{0}>\"." },
-    // 3.1 Start-Tags, End-Tags, and Empty-Element Tags
-        { "ElementUnterminated", "Element type \"{0}\" must be followed by either attribute specifications, \">\" or \"/>\"." },
-        { "EqRequiredInAttribute", "Attribute name \"{0}\" must be followed by the ''='' character." },
-        { "AttributeNotUnique", "Attribute \"{1}\" was already specified for element \"{0}\"." },
-        { "ETagUnterminated", "The end-tag for element type \"{0}\" must end with a ''>'' delimiter." },
-        { "MarkupNotRecognizedInContent", "The content of elements must consist of well-formed character data or markup." },
-    // 4.1 Character and Entity References
-        { "ReferenceUnterminated", "The reference must be terminated by a ';' delimiter." },
-    // 4.3.2 Well-Formed Parsed Entities
-        { "ReferenceNotInOneEntity", "The reference must be entirely contained within the same parsed entity." },
-        { "ElementEntityMismatch", "The element \"{0}\" must start and end within the same entity." },
-// Messages common to Document and DTD
-    // 2.2 Characters
-        { "InvalidCharInAttValue", "An invalid XML character (Unicode: 0x{2}) was found in the value of attribute \"{1}\"." },
-        { "InvalidCharInComment", "An invalid XML character (Unicode: 0x{0}) was found in the comment." },
-        { "InvalidCharInPI", "An invalid XML character (Unicode: 0x{0}) was found in the processing instruction." },
-        { "InvalidCharInInternalSubset", "An invalid XML character (Unicode: 0x{0}) was found in the internal subset of the DTD." },
-        { "InvalidCharInTextDecl", "An invalid XML character (Unicode: 0x{0}) was found in the text declaration." },
-    // 2.3 Common Syntactic Constructs
-        { "QuoteRequiredInAttValue", "The value of attribute \"{1}\" must begin with either a single or double quote character." },
-        { "LessthanInAttValue", "The value of attribute \"{1}\" must not contain the ''<'' character." },
-        { "AttributeValueUnterminated", "The value for attribute \"{1}\" must end with the matching quote character." },
-    // 2.5 Comments
-        { "DashDashInComment", "The string \"--\" is not permitted within comments." },
-        { "CommentUnterminated", "The comment must end with \"-->\"." },
-    // 2.6 Processing Instructions
-        { "PITargetRequired", "The processing instruction must begin with the name of the target." },
-        { "SpaceRequiredInPI", "White space is required between the processing instruction target and data." },
-        { "PIUnterminated", "The processing instruction must end with \"?>\"." },
-        { "ReservedPITarget", "The processing instruction target matching \"[xX][mM][lL]\" is not allowed." },
-    // 2.8 Prolog and Document Type Declaration
-        { "VersionInfoInvalid", "Invalid version \"{0}\"." },
-        { "VersionNotSupported", "XML version \"{0}\" is not supported." },
-    // 4.1 Character and Entity References
-        { "DigitRequiredInCharRef", "A decimal representation must immediately follow the \"&#\" in a character reference." },
-        { "HexdigitRequiredInCharRef", "A hexadecimal representation must immediately follow the \"&#x\" in a character reference." },
-        { "SemicolonRequiredInCharRef", "The character reference must end with the ';' delimiter." },
-        { "InvalidCharRef", "Character reference \"&#{0}\" is an invalid XML character." },
-        { "NameRequiredInReference", "The entity name must immediately follow the '&' in the entity reference." },
-        { "SemicolonRequiredInReference", "The reference to entity \"{0}\" must end with the '';'' delimiter." },
-    // 4.3.1 The Text Declaration
-        { "TextDeclMustBeFirst", "The text declaration may only appear at the very beginning of the external parsed entity." },
-        { "EqRequiredInTextDecl", "The ''='' character must follow \"{0}\" in the text declaration." },
-        { "QuoteRequiredInTextDecl", "The value following \"{0}\" in the text declaration must be a quoted string." },
-        { "SpaceRequiredInTextDecl", "White space is required between the version and the encoding declaration." },
-        { "TextDeclUnterminated", "The text declaration must end with \"?>\"." },
-        { "EncodingDeclRequired", "The encoding declaration is required in the text declaration." },
-    // 4.3.2 Well-Formed Parsed Entities
-        { "CommentNotInOneEntity", "The comment must be entirely contained within the same parsed entity." },
-        { "PINotInOneEntity", "The processing instruction must be entirely contained within the same parsed entity." },
-    // 4.3.3 Character Encoding in Entities
-        { "EncodingDeclInvalid", "Invalid encoding name \"{0}\"." },
-// DTD Messages
-    // 2.2 Characters
-        { "InvalidCharInEntityValue", "An invalid XML character (Unicode: 0x{0}) was found in the literal entity value." },
-        { "InvalidCharInExternalSubset", "An invalid XML character (Unicode: 0x{0}) was found in the external subset of the DTD." },
-        { "InvalidCharInIgnoreSect", "An invalid XML character (Unicode: 0x{0}) was found in the excluded conditional section." },
-        { "InvalidCharInPublicID", "An invalid XML character (Unicode: 0x{0}) was found in the public identifier." },
-        { "InvalidCharInSystemID", "An invalid XML character (Unicode: 0x{0}) was found in the system identifier." },
-    // 2.3 Common Syntactic Constructs
-        { "QuoteRequiredInSystemID", "The system identifier must begin with either a single or double quote character." },
-        { "SystemIDUnterminated", "The system identifier must end with the matching quote character." },
-        { "QuoteRequiredInPublicID", "The public identifier must begin with either a single or double quote character." },
-        { "PublicIDUnterminated", "The public identifier must end with the matching quote character." },
-        { "PubidCharIllegal", "The character (Unicode: 0x{0}) is not permitted in the public identifier." },
-    // 2.8 Prolog and Document Type Declaration
-        { "MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL", "White space is required after \"<!DOCTYPE\" in the document type declaration." },
-        { "MSG_ROOT_ELEMENT_TYPE_REQUIRED", "The root element type must appear after \"<!DOCTYPE\" in the document type declaration." },
-        { "DoctypedeclUnterminated", "The document type declaration for root element type \"{0}\" must end with ''>''." },
-        { "PEReferenceWithinMarkup", "The parameter entity reference \"%{0};\" cannot occur within markup in the internal subset of the DTD." },
-        { "MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", "The markup declarations contained or pointed to by the document type declaration must be well-formed." },
-    // 2.10 White Space Handling
-        { "MSG_XML_SPACE_DECLARATION_ILLEGAL", "The attribute declaration for \"xml:space\" must be given as an enumerated type whose only possible values are \"default\" and \"preserve\"." },
-    // 3.2 Element Type Declarations
-        { "MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ELEMENTDECL", "White space is required after \"<!ELEMENT\" in the element type declaration." },
-        { "MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL", "The element type is required in the element type declaration." },
-        { "MSG_SPACE_REQUIRED_BEFORE_CONTENTSPEC_IN_ELEMENTDECL", "White space is required after the element type \"{0}\" in the element type declaration." },
-        { "MSG_CONTENTSPEC_REQUIRED_IN_ELEMENTDECL", "The constraint is required after the element type \"{0}\" in the element type declaration." },
-        { "ElementDeclUnterminated", "The declaration for element type \"{0}\" must end with ''>''." },
-    // 3.2.1 Element Content
-        { "MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN", "A ''('' character or an element type is required in the declaration of element type \"{0}\"." },
-        { "MSG_CLOSE_PAREN_REQUIRED_IN_CHILDREN", "A '')'' is required in the declaration of element type \"{0}\"." },
-    // 3.2.2 Mixed Content
-        { "MSG_ELEMENT_TYPE_REQUIRED_IN_MIXED_CONTENT", "An element type is required in the declaration of element type \"{0}\"." },
-        { "MSG_CLOSE_PAREN_REQUIRED_IN_MIXED", "A '')'' is required in the declaration of element type \"{0}\"." },
-        { "MixedContentUnterminated", "The mixed content model \"{0}\" must end with \")*\" when the types of child elements are constrained." },
-    // 3.3 Attribute-List Declarations
-        { "MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ATTLISTDECL", "White space is required after \"<!ATTLIST\" in the attribute-list declaration." },
-        { "MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL", "The element type is required in the attribute-list declaration." },
-        { "MSG_SPACE_REQUIRED_BEFORE_ATTRIBUTE_NAME_IN_ATTDEF", "White space is required before the attribute name in the attribute-list declaration for element \"{0}\"." },
-        { "AttNameRequiredInAttDef", "The attribute name must be specified in the attribute-list declaration for element \"{0}\"." },
-        { "MSG_SPACE_REQUIRED_BEFORE_ATTTYPE_IN_ATTDEF", "White space is required before the attribute type in the declaration of attribute \"{1}\" for element \"{0}\"." },
-        { "AttTypeRequiredInAttDef", "The attribute type is required in the declaration of attribute \"{1}\" for element \"{0}\"." },
-        { "MSG_SPACE_REQUIRED_BEFORE_DEFAULTDECL_IN_ATTDEF", "White space is required before the attribute default in the declaration of attribute \"{1}\" for element \"{0}\"." },
-    // 3.3.1 Attribute Types
-        { "MSG_SPACE_REQUIRED_AFTER_NOTATION_IN_NOTATIONTYPE", "White space must appear after \"NOTATION\" in the \"{1}\" attribute declaration." },
-        { "MSG_OPEN_PAREN_REQUIRED_IN_NOTATIONTYPE", "The ''('' character must follow \"NOTATION\" in the \"{1}\" attribute declaration." },
-        { "MSG_NAME_REQUIRED_IN_NOTATIONTYPE", "The notation name is required in the notation type list for the \"{1}\" attribute declaration." },
-        { "NotationTypeUnterminated", "The notation type list must end with '')'' in the \"{1}\" attribute declaration." },
-        { "MSG_NMTOKEN_REQUIRED_IN_ENUMERATION", "The name token is required in the enumerated type list for the \"{1}\" attribute declaration." },
-        { "EnumerationUnterminated", "The enumerated type list must end with '')'' in the \"{1}\" attribute declaration." },
-    // 3.3.2 Attribute Defaults
-        { "MSG_SPACE_REQUIRED_AFTER_FIXED_IN_DEFAULTDECL", "White space must appear after \"FIXED\" in the \"{1}\" attribute declaration." },
-    // 3.4 Conditional Sections
-        { "IncludeSectUnterminated", "The included conditional section must end with \"]]>\"." },
-        { "IgnoreSectUnterminated", "The excluded conditional section must end with \"]]>\"." },
-    // 4.1 Character and Entity References
-        { "NameRequiredInPEReference", "The entity name must immediately follow the '%' in the parameter entity reference." },
-        { "SemicolonRequiredInPEReference", "The parameter entity reference \"%{0};\" must end with the '';'' delimiter." },
-    // 4.2 Entity Declarations
-        { "MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_ENTITYDECL", "White space is required after \"<!ENTITY\" in the entity declaration." },
-        { "MSG_SPACE_REQUIRED_BEFORE_PERCENT_IN_PEDECL", "White space is required between \"<!ENTITY\" and the '%' character in the parameter entity declaration." },
-        { "MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_PEDECL", "White space is required between the '%' and the entity name in the parameter entity declaration." },
-        { "MSG_ENTITY_NAME_REQUIRED_IN_ENTITYDECL", "The name of the entity is required in the entity declaration." },
-        { "MSG_SPACE_REQUIRED_AFTER_ENTITY_NAME_IN_ENTITYDECL", "White space is required between the entity name \"{0}\" and the definition in the entity declaration." },
-        { "MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_UNPARSED_ENTITYDECL", "White space is required between \"NDATA\" and the notation name in the declaration for the entity \"{0}\"." },
-        { "MSG_NOTATION_NAME_REQUIRED_FOR_UNPARSED_ENTITYDECL", "The notation name is required after \"NDATA\" in the declaration for the entity \"{0}\"." },
-        { "EntityDeclUnterminated", "The declaration for the entity \"{0}\" must end with ''>''." },
-    // 4.2.2 External Entities
-        { "ExternalIDRequired", "The external entity declaration must begin with either \"SYSTEM\" or \"PUBLIC\"." },
-        { "MSG_SPACE_REQUIRED_BEFORE_PUBIDLITERAL_IN_EXTERNALID", "White space is required between \"PUBLIC\" and the public identifier." },
-        { "MSG_SPACE_REQUIRED_AFTER_PUBIDLITERAL_IN_EXTERNALID", "White space is required between the public identifier and the system identifier." },
-        { "MSG_SPACE_REQUIRED_BEFORE_SYSTEMLITERAL_IN_EXTERNALID", "White space is required between \"SYSTEM\" and the system identifier." },
-        { "MSG_URI_FRAGMENT_IN_SYSTEMID", "The fragment identifier should not be specified as part of the system identifier \"{0}\"." },
-    // 4.7 Notation Declarations
-        { "MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_NOTATIONDECL", "White space is required after \"<!NOTATION\" in the notation declaration." },
-        { "MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL", "The name of the notation is required in the notation declaration." },
-        { "MSG_SPACE_REQUIRED_AFTER_NOTATION_NAME_IN_NOTATIONDECL", "White space is required after the notation name \"{0}\" in the notation declaration." },
-        { "NotationDeclUnterminated", "The declaration for the notation \"{0}\" must end with ''>''." },
-// Validation messages
-        { "DuplicateTypeInMixedContent", "The element type \"{0}\" was already specified in this content model." },
-        { "ENTITIESInvalid", "Attribute value \"{1}\" of type ENTITIES must be the names of one or more unparsed entities." },
-        { "ENTITYInvalid", "Attribute value \"{1}\" of type ENTITY must be the name of an unparsed entity." },
-        { "IDDefaultTypeInvalid", "The ID attribute \"{0}\" must have a declared default of \"#IMPLIED\" or \"#REQUIRED\"." },
-        { "IDInvalid", "Attribute value \"{1}\" of type ID must be a name." },
-        { "IDNotUnique", "Attribute value \"{1}\" of type ID must be unique within the document." },
-        { "IDREFInvalid", "Attribute value \"{1}\" of type IDREF must be a name." },
-        { "IDREFSInvalid", "Attribute value \"{0}\" of type IDREFS must be one or more names." },
-        { "ImproperDeclarationNesting", "The replacement text of parameter entity \"{0}\" must include properly nested declarations." },
-        { "ImproperGroupNesting", "The replacement text of parameter entity \"{0}\" must include properly nested pairs of parentheses." },
-        { "MSG_ATTRIBUTE_NOT_DECLARED", "Attribute \"{1}\" must be declared for element type \"{0}\"." },
-        { "MSG_ATTRIBUTE_VALUE_NOT_IN_LIST", "Attribute \"{0}\" with value \"{1}\" must have a value from the list \"{2}\"." },
-        { "MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE", "The value \"{1}\" of attribute \"{0}\" must not be changed by normalization (to \"{2}\") in a standalone document." },
-        { "MSG_CONTENT_INCOMPLETE", "The content of element type \"{0}\" is incomplete, it must match \"{1}\"." },
-        { "MSG_CONTENT_INVALID", "The content of element type \"{0}\" must match \"{1}\"." },
-        { "MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED", "Attribute \"{1}\" for element type \"{0}\" has a default value and must be specified in a standalone document." },
-        { "MSG_DUPLICATE_ATTDEF", "Attribute \"{1}\" is already declared for element type \"{0}\"." },
-        { "MSG_ELEMENT_ALREADY_DECLARED", "Element type \"{0}\" must not be declared more than once." },
-        { "MSG_ELEMENT_NOT_DECLARED", "Element type \"{0}\" must be declared." },
-        { "MSG_ELEMENT_WITH_ID_REQUIRED", "An element with the identifier \"{0}\" must appear in the document." },
-        { "MSG_EXTERNAL_ENTITY_NOT_PERMITTED", "The reference to external entity \"{0}\" is not permitted in a standalone document." },
-        { "MSG_FIXED_ATTVALUE_INVALID", "Attribute \"{1}\" with value \"{2}\" must have a value of \"{3}\"." },
-        { "MSG_MORE_THAN_ONE_ID_ATTRIBUTE", "Element type \"{0}\" already has attribute \"{1}\" of type ID, a second attribute \"{2}\" of type ID is not permitted." },
-        { "MSG_MORE_THAN_ONE_NOTATION_ATTRIBUTE", "Element type \"{0}\" already has attribute \"{1}\" of type NOTATION, a second attribute \"{2}\" of type NOTATION is not permitted." },
-        { "MSG_NOTATION_NOT_DECLARED_FOR_NOTATIONTYPE_ATTRIBUTE", "The notation \"{2}\" must be declared when referenced in the notation type list for attribute \"{1}\"." },
-        { "MSG_NOTATION_NOT_DECLARED_FOR_UNPARSED_ENTITYDECL", "The notation \"{1}\" must be declared when referenced in the unparsed entity declaration for \"{0}\"." },
-        { "MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE", "The reference to entity \"{0}\" declared in an external parsed entity is not permitted in a standalone document." },
-        { "MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED", "Attribute \"{1}\" is required and must be specified for element type \"{0}\"." },
-        { "MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE", "White space must not occur between elements declared in an external parsed entity with element content in a standalone document." },
-        { "NMTOKENInvalid", "Attribute value \"{1}\" of type NMTOKEN must be a name token." },
-        { "NMTOKENSInvalid", "Attribute value \"{0}\" of type NMTOKENS must be one or more name tokens." },
-        { "RootElementTypeMustMatchDoctypedecl", "Document root element \"{1}\", must match DOCTYPE root \"{0}\"." },
-        { "UndeclaredElementInContentSpec", "The content model of element \"{0}\" refers to the undeclared element \"{1}\"." },
-// Entity related messages
-    // 3.1 Start-Tags, End-Tags, and Empty-Element Tags
-        { "ReferenceToExternalEntity", "The external entity reference \"&{0};\" is not permitted in an attribute value." },
-    // 4.1 Character and Entity References
-        { "EntityNotDeclared", "The entity \"{0}\" was referenced, but not declared." },
-        { "ReferenceToUnparsedEntity", "The unparsed entity reference \"&{0};\" is not permitted." },
-        { "RecursiveReference", "Recursive reference \"&{0};\". (Reference path: {1})" },
-        { "RecursivePEReference", "Recursive reference \"%{0};\". (Reference path: {1})" },
-    // 4.3.3 Character Encoding in Entities
-        { "EncodingNotSupported", "The encoding \"{0}\" is not supported." },
-        { "EncodingRequired", "A parsed entity not encoded in either UTF-8 or UTF-16 must contain an encoding declaration." },
-// Namespaces support
-    // 4. Using Qualified Names
-        { "PrefixDeclared", "The namespace prefix \"{0}\" was not declared." },
-        { "MSG_ATT_DEFAULT_INVALID", "The defaultValue \"{1}\" of attribute \"{0}\" is not legal as for the lexical constraints of this attribute type." },
-        { "MSG_GENERIC_SCHEMA_ERROR", "General Schema Error: {0}." },
-
-    };
-
-    /** Returns the list resource bundle contents. */
-    public Object[][] getContents() {
-        return CONTENTS;
-    }
-}
diff --git a/src/org/apache/xerces/readers/AbstractCharReader.java b/src/org/apache/xerces/readers/AbstractCharReader.java
deleted file mode 100644
index 2ef4560..0000000
--- a/src/org/apache/xerces/readers/AbstractCharReader.java
+++ /dev/null
@@ -1,1397 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.CharDataChunk;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringHasher;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.utils.XMLCharacterProperties;
-import org.apache.xerces.utils.ImplementationMessages;
-import org.xml.sax.SAXParseException;
-import java.util.Vector;
-
-/**
- * An abstract class for readers that process input data as characters.
- * <p>
- * This is the base class of the CharReader and UTF8CharReader classes.
- * The CharReader classes fills in the "chunks" of data to process from
- * a character stream (java.io.Reader).  The UTF8CharReader performs
- * its own UTF-8 transcoding to fill in the data from an InputStream.
- *
- * @version $Id$
- */
-abstract class AbstractCharReader extends XMLEntityReader {
-
-    /**
-     * Subclass constructor
-     *
-     * @param entityHandler The entity handler.
-     * @param errorReporter The error reporter.
-     * @param sendCharDataAsCharArray true if char data should be reported using
-     *                                char arrays instead of string handles.
-     * @param stringPool The string pool.
-     */
-    protected AbstractCharReader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter, boolean sendCharDataAsCharArray, StringPool stringPool) {
-        super(entityHandler, errorReporter, sendCharDataAsCharArray);
-        fStringPool = stringPool;
-        fCurrentChunk = CharDataChunk.createChunk(fStringPool, null);
-    }
-
-    //
-    // These instance variables are referenced and updated directly
-    // by our subclass from the fillCurrentChunk() method.
-    //
-    protected CharDataChunk fCurrentChunk = null;
-    protected int fCurrentIndex = 0;
-    protected char[] fMostRecentData = null;
-    protected int fMostRecentChar = 0;
-    protected int fLength = 0;
-
-    /**
-     * Fill the current chunk the next buffer worth of data.
-     *
-     * This method should replace any 0xD,0xA sequence with a single
-     * 0xA character, and replace single 0xD characters with a 0xA
-     * character.  This is described in the spec under section 2.11,
-     * "End-of-Line Handling".
-     * 
-     * @return The value of the first character available for processing.
-     * @exception java.lang.Exception
-     */
-    protected abstract int fillCurrentChunk() throws Exception;
-
-    /**
-     * Delay reporting an error message.
-     *
-     * If there is an error detected in the underlying input stream during
-     * the fillCurrentChunk method, the error is described here and will be
-     * reported when we reach that offset during normal processing.  The
-     * subclass should place a character with a value of zero at that offset,
-     * which will be detected here as an invalid character.  When the invalid
-     * character is scanned, we will generate the deferred exception.
-     *
-     * @param errorCode the errorCode to report
-     * @param args an array of arguments needed to generate a good error message
-     * @param offset the position in the reader where the error occured
-     */
-    protected void deferException(int errorCode, Object[] args, int offset) {
-        if (fDeferredErrors == null)
-            fDeferredErrors = new Vector();
-        DeferredError de = new DeferredError(errorCode, args, offset);
-        fDeferredErrors.addElement(de);
-    }
-
-    /**
-     * Change readers at end of input.
-     *
-     * We override our superclass method to release the final chunk
-     * of the input data before handing off to the next reader.
-     *
-     * @return The next reader used to continue processing the document.
-     */
-    protected XMLEntityHandler.EntityReader changeReaders() throws Exception {
-        XMLEntityHandler.EntityReader nextReader = super.changeReaders();
-        fCurrentChunk.releaseChunk();
-        fCurrentChunk = null;
-        return nextReader;
-    }
-
-    //
-    // XMLEntityHandler.EntityReader implementation
-    //
-    // The first five methods of the interface are implemented
-    // in the XMLEntityHandler base class for us, namely
-    //
-    //    public int currentOffset();
-    //    public int getLineNumber();
-    //    public int getColumnNumber();
-    //    public void setInCDSect(boolean inCDSect);
-    //    public boolean getInCDSect();
-    //
-
-    /**
-     * Append the characters processed by this reader associated with <code>offset</code> and
-     * <code>length</code> to the <code>CharBuffer</code>.
-     *
-     * @param charBuffer The <code>CharBuffer</code> to append the characters to.
-     * @param offset The offset within this reader where the copy should start.
-     * @param length The length within this reader where the copy should stop.
-     */
-    public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length) {
-        fCurrentChunk.append(charBuffer, offset, length);
-    }
-
-    /**
-     * Add a string to the <code>StringPool</code> from the characters scanned using this
-     * reader as described by <code>offset</code> and <code>length</code>.
-     *
-     * @param offset The offset within this reader where the characters start.
-     * @param length The length within this reader where the characters end.
-     * @return The <code>StringPool</code> handle for the string.
-     */
-    public int addString(int offset, int length) {
-        if (length == 0)
-            return 0;
-        return fCurrentChunk.addString(offset, length);
-    }
-
-    /**
-     * Add a symbol to the <code>StringPool</code> from the characters scanned using this
-     * reader as described by <code>offset</code> and <code>length</code>.
-     *
-     * @param offset The offset within this reader where the characters start.
-     * @param length The length within this reader where the characters end.
-     * @return The <code>StringPool</code> handle for the symbol.
-     */
-    public int addSymbol(int offset, int length) {
-        if (length == 0)
-            return 0;
-        return fCurrentChunk.addSymbol(offset, length, 0);
-    }
-
-    /**
-     *
-     */
-    public boolean lookingAtChar(char chr, boolean skipPastChar) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch != chr) {
-            if (ch == 0) {
-                if (atEOF(fCurrentOffset + 1)) {
-                    return changeReaders().lookingAtChar(chr, skipPastChar);
-                }
-            }
-            return false;
-        }
-        if (skipPastChar) {
-            fCharacterCounter++;
-            fCurrentOffset++;
-            if (++fCurrentIndex == CharDataChunk.CHUNK_SIZE)
-                slowLoadNextChar();
-            else
-                fMostRecentChar = fMostRecentData[fCurrentIndex] & 0xFFFF;
-        }
-        return true;
-    }
-
-    /**
-     *
-     */
-    public boolean lookingAtValidChar(boolean skipPastChar) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch < 0xD800) {
-            if (ch >= 0x20 || ch == 0x09) {
-                if (skipPastChar) {
-                    fCharacterCounter++;
-                    loadNextChar();
-                }
-                return true;
-            }
-            if (ch == 0x0A) {
-                if (skipPastChar) {
-                    fLinefeedCounter++;
-                    fCharacterCounter = 1;
-                    loadNextChar();
-                }
-                return true;
-            }
-            if (ch == 0) {
-                if (atEOF(fCurrentOffset + 1)) {
-                    return changeReaders().lookingAtValidChar(skipPastChar);
-                }
-            }
-            return false;
-        }
-        if (ch > 0xFFFD) {
-            return false;
-        }
-        if (ch < 0xDC00) {
-            CharDataChunk savedChunk = fCurrentChunk;
-            int savedIndex = fCurrentIndex;
-            int savedOffset = fCurrentOffset;
-            ch = loadNextChar();
-            boolean valid = (ch >= 0xDC00 && ch < 0xE000);
-            if (!valid || !skipPastChar) {
-                fCurrentChunk = savedChunk;
-                fCurrentIndex = savedIndex;
-                fCurrentOffset = savedOffset;
-                fMostRecentData = savedChunk.toCharArray();
-                fMostRecentChar = fMostRecentData[savedIndex] & 0xFFFF;
-                return valid;
-            }
-        } else if (ch < 0xE000) {
-            return false;
-        }
-        if (skipPastChar) {
-            fCharacterCounter++;
-            loadNextChar();
-        }
-        return true;
-    }
-
-    /**
-     *
-     */
-    public boolean lookingAtSpace(boolean skipPastChar) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch > 0x20)
-            return false;
-        if (ch == 0x20 || ch == 0x09) {
-            if (!skipPastChar)
-                return true;
-            fCharacterCounter++;
-        } else if (ch == 0x0A) {
-            if (!skipPastChar)
-                return true;
-            fLinefeedCounter++;
-            fCharacterCounter = 1;
-        } else {
-            if (ch == 0) { // REVISIT - should we be checking this here ?
-                if (atEOF(fCurrentOffset + 1)) {
-                    return changeReaders().lookingAtSpace(skipPastChar);
-                }
-            }
-            return false;
-        }
-        fCurrentOffset++;
-        if (++fCurrentIndex == CharDataChunk.CHUNK_SIZE)
-            slowLoadNextChar();
-        else
-            fMostRecentChar = fMostRecentData[fCurrentIndex] & 0xFFFF;
-        return true;
-    }
-
-    /**
-     *
-     */
-    public void skipToChar(char chr) throws Exception {
-        //
-        // REVISIT - this will skip invalid characters without reporting them.
-        //
-        int ch = fMostRecentChar;
-        while (true) {
-            if (ch == chr)
-                return;
-            if (ch == 0) {
-                if (atEOF(fCurrentOffset + 1)) {
-                    changeReaders().skipToChar(chr);
-                    return;
-                }
-                fCharacterCounter++;
-            } else if (ch == 0x0A) {
-                fLinefeedCounter++;
-                fCharacterCounter = 1;
-            } else if (ch >= 0xD800 && ch < 0xDC00) {
-                fCharacterCounter++;
-                ch = loadNextChar();
-                if (ch < 0xDC00 || ch >= 0xE000)
-                    continue;
-            } else
-                fCharacterCounter++;
-            ch = loadNextChar();
-        }
-    }
-
-    /**
-     *
-     */
-    public void skipPastSpaces() throws Exception {
-        int ch = fMostRecentChar;
-        while (true) {
-            if (ch == 0x20 || ch == 0x09) {
-                fCharacterCounter++;
-            } else if (ch == 0x0A) {
-                fLinefeedCounter++;
-                fCharacterCounter = 1;
-            } else {
-                if (ch == 0 && atEOF(fCurrentOffset + 1))
-                    changeReaders().skipPastSpaces();
-                return;
-            }
-            ch = loadNextChar();
-        }
-    }
-
-    /**
-     *
-     */
-    public void skipPastName(char fastcheck) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch < 0x80) {
-            if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0)
-                return;
-        } else {
-            if ( ! fCalledCharPropInit) {
-                XMLCharacterProperties.initCharFlags();
-                fCalledCharPropInit = true;
-            }
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
-                return;
-        }
-        while (true) {
-            fCharacterCounter++;
-            ch = loadNextChar();
-            if (fastcheck == ch)
-                return;
-            if (ch < 0x80) {
-                if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                    return;
-            } else {
-                if (!fCalledCharPropInit) {
-                    XMLCharacterProperties.initCharFlags();
-                    fCalledCharPropInit = true;
-                }
-                if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                    return;
-            }
-        }
-    }
-
-    /**
-     *
-     */
-    public void skipPastNmtoken(char fastcheck) throws Exception {
-        int ch = fMostRecentChar;
-        while (true) {
-            if (fastcheck == ch)
-                return;
-            if (ch < 0x80) {
-                if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                    return;
-            } else {
-                if (!fCalledCharPropInit) {
-                    XMLCharacterProperties.initCharFlags();
-                    fCalledCharPropInit = true;
-                }
-                if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                    return;
-            }
-            fCharacterCounter++;
-            ch = loadNextChar();
-        }
-    }
-
-    /**
-     *
-     */
-    public boolean skippedString(char[] s) throws Exception {
-        int length = s.length;
-        char[] data = fMostRecentData;
-        int index = fCurrentIndex;
-        if (index + length <= CharDataChunk.CHUNK_SIZE) {
-            for (int i = 0; i < length; i++) {
-                if (data[index++] != s[i])
-                    return false;
-            }
-            fCharacterCounter += length;
-            fCurrentOffset += length;
-            fCurrentIndex = index;
-            if (index == CharDataChunk.CHUNK_SIZE)
-                slowLoadNextChar();
-            else
-                fMostRecentChar = data[index] & 0xFFFF;
-            return true;
-        }
-        CharDataChunk dataChunk = fCurrentChunk;
-        int offset = fCurrentOffset;
-        int savedIndex = index;
-        int i = 0;
-        while (index < CharDataChunk.CHUNK_SIZE) {
-            if (data[index++] != s[i++])
-                return false;
-        }
-        slowLoadNextChar();
-        data = fMostRecentData;
-        index = 0;
-        while (i < length) {
-            if (data[index++] != s[i++]) {
-                fCurrentChunk = dataChunk;
-                fCurrentIndex = savedIndex;
-                fCurrentOffset = offset;
-                fMostRecentData = dataChunk.toCharArray();
-                fMostRecentChar = fMostRecentData[savedIndex] & 0xFFFF;
-                return false;
-            }
-        }
-        fCharacterCounter += length;
-        fCurrentOffset += length;
-        fCurrentIndex = index;
-        if (index == CharDataChunk.CHUNK_SIZE)
-            slowLoadNextChar();
-        else
-            fMostRecentChar = data[index] & 0xFFFF;
-        return true;
-    }
-
-    /**
-     *
-     */
-    public int scanInvalidChar() throws Exception {
-        int ch = fMostRecentChar;
-        if (ch == 0x0A) {
-            fLinefeedCounter++;
-            fCharacterCounter = 1;
-            loadNextChar();
-        } else if (ch == 0) {
-            if (atEOF(fCurrentOffset + 1)) {
-                return changeReaders().scanInvalidChar();
-            }
-            if (fDeferredErrors != null) {
-                for (int i = 0; i < fDeferredErrors.size(); i++) {
-                    DeferredError de = (DeferredError)fDeferredErrors.elementAt(i);
-                    if (de.offset == fCurrentIndex) {
-                        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                                   ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
-                                                   de.errorCode,
-                                                   0,
-                                                   de.args,
-                                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-                        fDeferredErrors.removeElementAt(i);
-                        fCharacterCounter++;
-                        loadNextChar();
-                        return -1;
-                    }
-                }
-            }
-            fCharacterCounter++;
-            loadNextChar();
-        } else {
-            fCharacterCounter++;
-            if (ch >= 0xD800 && ch < 0xDC00) {
-                int ch2 = loadNextChar();
-                if (ch2 >= 0xDC00 && ch2 < 0xE000) {
-                    ch = ((ch-0xD800)<<10)+(ch2-0xDC00)+0x10000;
-                    loadNextChar();
-                }
-            } else
-                loadNextChar();
-        }
-        return ch;
-    }
-
-    /**
-     *
-     */
-    public int scanCharRef(boolean hex) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch == 0) {
-            if (atEOF(fCurrentOffset + 1)) {
-                return changeReaders().scanCharRef(hex);
-            }
-            return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-        }
-        int num = 0;
-        if (hex) {
-            if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
-                return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-            num = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
-        } else {
-            if (ch < '0' || ch > '9')
-                return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-            num = ch - '0';
-        }
-        fCharacterCounter++;
-        loadNextChar();
-        boolean toobig = false;
-        while (true) {
-            ch = fMostRecentChar;
-            if (ch == 0)
-                break;
-            if (hex) {
-                if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
-                    break;
-            } else {
-                if (ch < '0' || ch > '9')
-                    break;
-            }
-            fCharacterCounter++;
-            loadNextChar();
-            if (hex) {
-                int dig = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
-                num = (num << 4) + dig;
-            } else {
-                int dig = ch - '0';
-                num = (num * 10) + dig;
-            }
-            if (num > 0x10FFFF) {
-                toobig = true;
-                num = 0;
-            }
-        }
-        if (ch != ';')
-            return XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED;
-        fCharacterCounter++;
-        loadNextChar();
-        if (toobig)
-            return XMLEntityHandler.CHARREF_RESULT_OUT_OF_RANGE;
-        return num;
-    }
-
-    /**
-     *
-     */
-    public int scanStringLiteral() throws Exception {
-        boolean single;
-        if (!(single = lookingAtChar('\'', true)) && !lookingAtChar('\"', true)) {
-            return XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED;
-        }
-        int offset = fCurrentOffset;
-        char qchar = single ? '\'' : '\"';
-        while (!lookingAtChar(qchar, false)) {
-            if (!lookingAtValidChar(true)) {
-                return XMLEntityHandler.STRINGLIT_RESULT_INVALID_CHAR;
-            }
-        }
-        int stringIndex = addString(offset, fCurrentOffset - offset);
-        lookingAtChar(qchar, true); // move past qchar
-        return stringIndex;
-    }
-
-    //
-    // [10] AttValue ::= '"' ([^<&"] | Reference)* '"'
-    //                   | "'" ([^<&'] | Reference)* "'"
-    //
-    /**
-     *
-     */
-    public int scanAttValue(char qchar, boolean asSymbol) throws Exception
-    {
-        int offset = fCurrentOffset;
-        while (true) {
-            if (lookingAtChar(qchar, false)) {
-                break;
-            }
-            if (lookingAtChar(' ', true)) {
-                continue;
-            }
-            if (lookingAtSpace(false)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_COMPLEX;
-            }
-            if (lookingAtChar('&', false)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_COMPLEX;
-            }
-            if (lookingAtChar('<', false)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_LESSTHAN;
-            }
-            if (!lookingAtValidChar(true)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_INVALID_CHAR;
-            }
-        }
-        int result = asSymbol ? addSymbol(offset, fCurrentOffset - offset) : addString(offset, fCurrentOffset - offset);
-        lookingAtChar(qchar, true);
-        return result;
-    }
-
-    //
-    //  [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
-    //                      | "'" ([^%&'] | PEReference | Reference)* "'"
-    //
-    /**
-     *
-     */
-    public int scanEntityValue(int qchar, boolean createString) throws Exception
-    {
-        int offset = fCurrentOffset;
-        while (true) {
-            if (atEOF(fCurrentOffset + 1)) {
-                changeReaders();
-                return XMLEntityHandler.ENTITYVALUE_RESULT_END_OF_INPUT;
-            }
-            if (qchar != -1 && lookingAtChar((char)qchar, false)) {
-                if (!createString)
-                    return XMLEntityHandler.ENTITYVALUE_RESULT_FINISHED;
-                break;
-            }
-            if (lookingAtChar('&', false)) {
-                return XMLEntityHandler.ENTITYVALUE_RESULT_REFERENCE;
-            }
-            if (lookingAtChar('%', false)) {
-                return XMLEntityHandler.ENTITYVALUE_RESULT_PEREF;
-            }
-            if (!lookingAtValidChar(true)) {
-                return XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR;
-            }
-        }
-        int result = addString(offset, fCurrentOffset - offset);
-        lookingAtChar((char)qchar, true);
-        return result;
-    }
-
-    /**
-     *
-     */
-    public int scanName(char fastcheck) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch < 0x80) {
-            if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0)
-                return -1;
-        } else {
-            if (!fCalledCharPropInit) {
-                XMLCharacterProperties.initCharFlags();
-                fCalledCharPropInit = true;
-            }
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
-                return -1;
-        }
-        int offset = fCurrentOffset;
-        int index = fCurrentIndex;
-        char[] data = fMostRecentData;
-        if (++index == CharDataChunk.CHUNK_SIZE) {
-            slowLoadNextChar();
-            index = 0;
-            data = fMostRecentData;
-        }
-        fCharacterCounter++;
-        fCurrentOffset++;
-        int hashcode = 0;
-        while (true) {
-            hashcode = StringHasher.hashChar(hashcode, ch);
-            ch = data[index] & 0xFFFF;
-            if (fastcheck == ch)
-                break;
-            if (ch < 0x80) {
-                if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                    break;
-            } else {
-                if (!fCalledCharPropInit) {
-                    XMLCharacterProperties.initCharFlags();
-                    fCalledCharPropInit = true;
-                }
-                if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                    break;
-            }
-            if (++index == CharDataChunk.CHUNK_SIZE) {
-                slowLoadNextChar();
-                index = 0;
-                data = fMostRecentData;
-            }
-            fCharacterCounter++;
-            fCurrentOffset++;
-        }
-        fCurrentIndex = index;
-        fMostRecentChar = ch;
-        hashcode = StringHasher.finishHash(hashcode);
-        int length = fCurrentOffset - offset;
-        int nameIndex = fCurrentChunk.addSymbol(offset, length, hashcode);
-        return nameIndex;
-    }
-
-    /**
-     *
-     */
-    public boolean scanExpectedName(char fastcheck, StringPool.CharArrayRange expectedName) throws Exception {
-        char[] expected = expectedName.chars;
-        int offset = expectedName.offset;
-        int len = expectedName.length;
-        int ch = fMostRecentChar;
-        for (int i = 0; i < len; i++) {
-            if (ch != expected[offset++]) {
-                skipPastNmtoken(fastcheck);
-                return false;
-            }
-            fCharacterCounter++;
-            fCurrentOffset++;
-            if (++fCurrentIndex == CharDataChunk.CHUNK_SIZE)
-                ch = slowLoadNextChar();
-            else
-                ch = (fMostRecentChar = fMostRecentData[fCurrentIndex] & 0xFFFF);
-        }
-        if (ch == fastcheck)
-            return true;
-        if (ch < 0x80) {
-            if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                return true;
-        } else {
-            if (!fCalledCharPropInit) {
-                XMLCharacterProperties.initCharFlags();
-                fCalledCharPropInit = true;
-            }
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                return true;
-        }
-        skipPastNmtoken(fastcheck);
-        return false;
-    }
-
-    /**
-     *
-     */
-    public void scanQName(char fastcheck, QName qname) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch < 0x80) {
-            if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0) {
-                qname.clear();
-                return;
-            }
-            if (ch == ':') {
-                qname.clear();
-                return;
-            }
-        } else {
-            if (!fCalledCharPropInit) {
-                XMLCharacterProperties.initCharFlags();
-                fCalledCharPropInit = true;
-            }
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0) {
-                qname.clear();
-                return;
-            }
-        }
-        int offset = fCurrentOffset;
-        int index = fCurrentIndex;
-        char[] data = fMostRecentData;
-        if (++index == CharDataChunk.CHUNK_SIZE) {
-            slowLoadNextChar();
-            index = 0;
-            data = fMostRecentData;
-        }
-        fCharacterCounter++;
-        fCurrentOffset++;
-        int hashcode = 0;
-        int prefixend = -1;
-        while (true) {
-            hashcode = StringHasher.hashChar(hashcode, ch);
-            ch = data[index] & 0xFFFF;
-            if (fastcheck == ch)
-                break;
-            if (ch < 0x80) {
-                if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                    break;
-                if (ch == ':') {
-                    if (prefixend != -1)
-                        break;
-                    prefixend = fCurrentOffset;
-                    //
-                    // We need to peek ahead one character.  If the next character is not a
-                    // valid initial name character, or is another colon, then we cannot meet
-                    // both the Prefix and LocalPart productions for the QName production,
-                    // which means that there is no Prefix and we need to terminate the QName
-                    // at the first colon.
-                    //
-                    if (index + 1 == CharDataChunk.CHUNK_SIZE) {
-                        CharDataChunk savedChunk = fCurrentChunk;
-                        int savedOffset = fCurrentOffset;
-                        ch = slowLoadNextChar();
-                        fCurrentChunk = savedChunk;
-                        fCurrentOffset = savedOffset;
-                        fMostRecentData = savedChunk.toCharArray();
-                    } else
-                        ch = data[index + 1] & 0xFFFF;
-                    boolean lpok = true;
-                    if (ch < 0x80) {
-                        if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0 || ch == ':')
-                            lpok = false;
-                    } else {
-                        if (!fCalledCharPropInit) {
-                            XMLCharacterProperties.initCharFlags();
-                            fCalledCharPropInit = true;
-                        }
-                        if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
-                            lpok = false;
-                    }
-                    ch = ':';
-                    if (!lpok) {
-                        prefixend = -1;
-                        break;
-                    }
-                }
-            } else {
-                if (!fCalledCharPropInit) {
-                    XMLCharacterProperties.initCharFlags();
-                    fCalledCharPropInit = true;
-                }
-                if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                    break;
-            }
-            if (++index == CharDataChunk.CHUNK_SIZE) {
-                slowLoadNextChar();
-                index = 0;
-                data = fMostRecentData;
-            }
-            fCharacterCounter++;
-            fCurrentOffset++;
-        }
-        fCurrentIndex = index;
-        fMostRecentChar = ch;
-        hashcode = StringHasher.finishHash(hashcode);
-        int length = fCurrentOffset - offset;
-        qname.rawname = fCurrentChunk.addSymbol(offset, length, hashcode);
-        qname.prefix = prefixend == -1 ? -1 : addSymbol(offset, prefixend - offset);
-        qname.localpart = prefixend == -1 ? qname.rawname : addSymbol(prefixend + 1, fCurrentOffset - (prefixend + 1));
-        qname.uri = -1;
-
-    } // scanQName(char,QName)
-
-    //
-    // [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
-    //
-    /**
-     *
-     */
-    public int scanContent(QName element) throws Exception {
-        if (fCallClearPreviousChunk && fCurrentChunk.clearPreviousChunk())
-            fCallClearPreviousChunk = false;
-        int charDataOffset = fCurrentOffset;
-        int ch = fMostRecentChar;
-        if (ch < 0x80) {
-            switch (XMLCharacterProperties.fgAsciiWSCharData[ch]) {
-            case 0:
-                fCharacterCounter++;
-                ch = loadNextChar();
-                break;
-            case 1: // '<'
-                fCharacterCounter++;
-                ch = loadNextChar();
-                if (!fInCDSect) {
-                    return recognizeMarkup(ch);
-                }
-                break;
-            case 2: // '&'
-                fCharacterCounter++;
-                ch = loadNextChar();
-                if (!fInCDSect) {
-                    return recognizeReference(ch);
-                }
-                break;
-            case 3: // ']'
-                fCharacterCounter++;
-                ch = loadNextChar();
-                if (ch != ']')
-                    break;
-                if (fCurrentIndex + 1 == CharDataChunk.CHUNK_SIZE) {
-                    CharDataChunk dataChunk = fCurrentChunk;
-                    int index = fCurrentIndex;
-                    int offset = fCurrentOffset;
-                    if (loadNextChar() != '>') {
-                        fCurrentChunk = dataChunk;
-                        fCurrentIndex = index;
-                        fCurrentOffset = offset;
-                        fMostRecentData = dataChunk.toCharArray();
-                        fMostRecentChar = ']';
-                        break;
-                    }
-                } else {
-                    if (fMostRecentData[fCurrentIndex + 1] != '>')
-                        break;
-                    fCurrentIndex++;
-                    fCurrentOffset++;
-                }
-                loadNextChar();
-                fCharacterCounter += 2;
-                return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-            case 4: // invalid char
-                if (ch == 0 && atEOF(fCurrentOffset + 1)) {
-                    changeReaders();
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR; // REVISIT - not quite...
-                }
-                return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-            case 5:
-                do {
-                    if (ch == 0x0A) {
-                        fLinefeedCounter++;
-                        fCharacterCounter = 1;
-                    } else
-                        fCharacterCounter++;
-                    ch = loadNextChar();
-                } while (ch == 0x20 || ch == 0x09 || ch == 0x0A);
-                if (ch < 0x80) {
-                    switch (XMLCharacterProperties.fgAsciiCharData[ch]) {
-                    case 0:
-                        fCharacterCounter++;
-                        ch = loadNextChar();
-                        break;
-                    case 1: // '<'
-                        if (!fInCDSect) {
-                            callCharDataHandler(charDataOffset, fCurrentOffset, true);
-                            fCharacterCounter++;
-                            ch = loadNextChar();
-                            return recognizeMarkup(ch);
-                        }
-                        fCharacterCounter++;
-                        ch = loadNextChar();
-                        break;
-                    case 2: // '&'
-                        if (!fInCDSect) {
-                            callCharDataHandler(charDataOffset, fCurrentOffset, true);
-                            fCharacterCounter++;
-                            ch = loadNextChar();
-                            return recognizeReference(ch);
-                        }
-                        fCharacterCounter++;
-                        ch = loadNextChar();
-                        break;
-                    case 3: // ']'
-                        int endOffset = fCurrentOffset;
-                        ch = loadNextChar();
-                        if (ch != ']') {
-                            fCharacterCounter++;
-                            break;
-                        }
-                        if (fCurrentIndex + 1 == CharDataChunk.CHUNK_SIZE) {
-                            CharDataChunk dataChunk = fCurrentChunk;
-                            int index = fCurrentIndex;
-                            int offset = fCurrentOffset;
-                            if (loadNextChar() != '>') {
-                                fCurrentChunk = dataChunk;
-                                fCurrentIndex = index;
-                                fCurrentOffset = offset;
-                                fMostRecentData = dataChunk.toCharArray();
-                                fMostRecentChar = ']';
-                                fCharacterCounter++;
-                                break;
-                            }
-                        } else {
-                            if (fMostRecentData[fCurrentIndex + 1] != '>') {
-                                fCharacterCounter++;
-                                break;
-                            }
-                            fCurrentIndex++;
-                            fCurrentOffset++;
-                        }
-                        loadNextChar();
-                        callCharDataHandler(charDataOffset, endOffset, true);
-                        fCharacterCounter += 3;
-                        return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-                    case 4: // invalid char
-                        callCharDataHandler(charDataOffset, fCurrentOffset, true);
-                        if (ch == 0 && atEOF(fCurrentOffset + 1)) {
-                            changeReaders();
-                            return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR; // REVISIT - not quite...
-                        }
-                        return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                    }
-                } else if (!skipMultiByteCharData(ch)) {
-                    callCharDataHandler(charDataOffset, fCurrentOffset, true);
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-                break;
-            }
-        } else if (!skipMultiByteCharData(ch)) {
-            return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-        }
-        ch = skipAsciiCharData();
-        while (true) {
-            if (ch < 0x80) {
-                switch (XMLCharacterProperties.fgAsciiCharData[ch]) {
-                case 0:
-                    fCharacterCounter++;
-                    ch = loadNextChar();
-                    break;
-                case 1: // '<'
-                    if (!fInCDSect) {
-                        callCharDataHandler(charDataOffset, fCurrentOffset, false);
-                        fCharacterCounter++;
-                        ch = loadNextChar();
-                        return recognizeMarkup(ch);
-                    }
-                    fCharacterCounter++;
-                    ch = loadNextChar();
-                    break;
-                case 2: // '&'
-                    if (!fInCDSect) {
-                        callCharDataHandler(charDataOffset, fCurrentOffset, false);
-                        fCharacterCounter++;
-                        ch = loadNextChar();
-                        return recognizeReference(ch);
-                    }
-                    fCharacterCounter++;
-                    ch = loadNextChar();
-                    break;
-                case 3: // ']'
-                    int endOffset = fCurrentOffset;
-                    ch = loadNextChar();
-                    if (ch != ']') {
-                        fCharacterCounter++;
-                        break;
-                    }
-                    if (fCurrentIndex + 1 == CharDataChunk.CHUNK_SIZE) {
-                        CharDataChunk dataChunk = fCurrentChunk;
-                        int index = fCurrentIndex;
-                        int offset = fCurrentOffset;
-                        if (loadNextChar() != '>') {
-                            fCurrentChunk = dataChunk;
-                            fCurrentIndex = index;
-                            fCurrentOffset = offset;
-                            fMostRecentData = dataChunk.toCharArray();
-                            fMostRecentChar = ']';
-                            fCharacterCounter++;
-                            break;
-                        }
-                    } else {
-                        if (fMostRecentData[fCurrentIndex + 1] != '>') {
-                            fCharacterCounter++;
-                            break;
-                        }
-                        fCurrentIndex++;
-                        fCurrentOffset++;
-                    }
-                    loadNextChar();
-                    callCharDataHandler(charDataOffset, endOffset, false);
-                    fCharacterCounter += 3;
-                    return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-                case 4: // invalid char
-                    if (ch == 0x0A) {
-                        fLinefeedCounter++;
-                        fCharacterCounter = 1;
-                        ch = loadNextChar();
-                        break;
-                    }
-                    callCharDataHandler(charDataOffset, fCurrentOffset, false);
-                    if (ch == 0 && atEOF(fCurrentOffset + 1)) {
-                        changeReaders();
-                        return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR; // REVISIT - not quite...
-                    }
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-            } else {
-                if (!skipMultiByteCharData(ch)) {
-                    callCharDataHandler(charDataOffset, fCurrentOffset, false);
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-                ch = fMostRecentChar;
-            }
-        }
-    }
-
-    //
-    // Private data members
-    //
-    private static final char[] cdata_string = { 'C','D','A','T','A','[' };
-    private StringPool fStringPool = null;
-    private boolean fCalledCharPropInit = false;
-    private boolean fCallClearPreviousChunk = true;
-    private Vector fDeferredErrors = null;
-
-    //
-    // Private classes
-    //
-    private class DeferredError {
-        int errorCode;
-        Object[] args;
-        int offset;
-        DeferredError(int ec, Object[] a, int o) {
-            errorCode = ec;
-            args = a;
-            offset = o;
-        }
-    }
-
-    //
-    // Private methods
-    //
-
-    /*
-     * Return a result code for scanContent when the character data
-     * ends with a less-than character.
-     */
-    private int recognizeMarkup(int ch) throws Exception {
-        switch (ch) {
-        case 0:
-            return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-        case '?':
-            fCharacterCounter++;
-            loadNextChar();
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_PI;
-        case '!':
-            fCharacterCounter++;
-            ch = loadNextChar();
-            if (ch == 0) {
-                fCharacterCounter--;
-                fCurrentOffset--;
-                return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-            }
-            if (ch == '-') {
-                fCharacterCounter++;
-                ch = loadNextChar();
-                if (ch == 0) {
-                    fCharacterCounter -= 2;
-                    fCurrentOffset -= 2;
-                    return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-                }
-                if (ch == '-') {
-                    fCharacterCounter++;
-                    loadNextChar();
-                    return XMLEntityHandler.CONTENT_RESULT_START_OF_COMMENT;
-                }
-                break;
-            }
-            if (ch == '[') {
-                for (int i = 0; i < 6; i++) {
-                    fCharacterCounter++;
-                    ch = loadNextChar();
-                    if (ch == 0) {
-                        fCharacterCounter -= (2 + i);
-                        fCurrentOffset -= (2 + i);
-                        return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-                    }
-                    if (ch != cdata_string[i]) {
-                        return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
-                    }
-                }
-                fCharacterCounter++;
-                loadNextChar();
-                return XMLEntityHandler.CONTENT_RESULT_START_OF_CDSECT;
-            }
-            break;
-        case '/':
-            fCharacterCounter++;
-            loadNextChar();
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ETAG;
-        default:
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ELEMENT;
-        }
-        return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
-    }
-
-    /*
-     * Return a result code for scanContent when the character data
-     * ends with an ampersand character.
-     */
-    private int recognizeReference(int ch) throws Exception {
-        if (ch == 0) {
-            return XMLEntityHandler.CONTENT_RESULT_REFERENCE_END_OF_INPUT;
-        }
-        //
-        // [67] Reference ::= EntityRef | CharRef
-        // [68] EntityRef ::= '&' Name ';'
-        // [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
-        //
-        if (ch == '#') {
-            fCharacterCounter++;
-            loadNextChar();
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_CHARREF;
-        } else {
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ENTITYREF;
-        }
-    }
-
-    /*
-     * Skip over a multi-byte character.
-     */
-    private boolean skipMultiByteCharData(int ch) throws Exception {
-        if (ch < 0xD800) {
-            loadNextChar();
-            return true;
-        }
-        if (ch > 0xFFFD)
-            return false;
-        if (ch >= 0xDC00 && ch < 0xE000)
-            return false;
-        if (ch >= 0xD800 && ch < 0xDC00) {
-            CharDataChunk savedChunk = fCurrentChunk;
-            int savedIndex = fCurrentIndex;
-            int savedOffset = fCurrentOffset;
-            ch = loadNextChar();
-            if (ch < 0xDC00 || ch >= 0xE000) {
-                fCurrentChunk = savedChunk;
-                fCurrentIndex = savedIndex;
-                fCurrentOffset = savedOffset;
-                fMostRecentData = savedChunk.toCharArray();
-                fMostRecentChar = fMostRecentData[savedIndex] & 0xFFFF;
-                return false;
-            }
-        }
-        loadNextChar();
-        return true;
-    }
-
-    /*
-     * Skip over contiguous ascii character data.
-     *
-     * @return the character skipped
-     * @exception java.lang.Exception
-     */
-    private int skipAsciiCharData() throws Exception {
-        int index = fCurrentIndex;
-        int offset = fCurrentOffset - index;
-        while (true) {
-            char[] data = fMostRecentData;
-            while (index < CharDataChunk.CHUNK_SIZE) {
-                int ch = data[index] & 0xFFFF;
-                if (ch >= 0x80) {
-                    fCurrentOffset = offset + index;
-                    fCurrentIndex = index;
-                    fMostRecentChar = ch;
-                    return ch;
-                }
-                if (XMLCharacterProperties.fgAsciiCharData[ch] == 0) {
-                    fCharacterCounter++;
-                } else if (ch == 0x0A) {
-                    fLinefeedCounter++;
-                    fCharacterCounter = 1;
-                } else {
-                    fCurrentOffset = offset + index;
-                    fCurrentIndex = index;
-                    fMostRecentChar = ch;
-                    return ch;
-                }
-                index++;
-            }
-            offset += index;
-            slowLoadNextChar();
-            index = 0;
-        }
-    }
-
-    /*
-     * Report character data to the parser through the entity handler interface.
-     *
-     * @param offset the offset of the start of the character data
-     * @param endOffset the offset of the end of the character data
-     * @param isWhitespace true if the character data is whitespace
-     * @exception java.lang.Exception
-     */
-    private void callCharDataHandler(int offset, int endOffset, boolean isWhitespace) throws Exception {
-
-        int length = endOffset - offset;
-        if (!fSendCharDataAsCharArray) {
-            int stringIndex = addString(offset, length);
-            if (isWhitespace)
-                fCharDataHandler.processWhitespace(stringIndex);
-            else
-                fCharDataHandler.processCharacters(stringIndex);
-            return;
-        }
-
-        CharDataChunk dataChunk = fCurrentChunk.chunkFor(offset);
-        int index = offset & CharDataChunk.CHUNK_MASK;
-        if (index + length <= CharDataChunk.CHUNK_SIZE) {
-            //
-            // All the chars are in the same chunk
-            //
-            if (length != 0) {
-                if (isWhitespace)
-                    fCharDataHandler.processWhitespace(dataChunk.toCharArray(), index, length);
-                else
-                    fCharDataHandler.processCharacters(dataChunk.toCharArray(), index, length);
-            }
-            return;
-        }
-
-        //
-        // The data is spread across chunks.
-        //
-        int count = length;
-        int nbytes = CharDataChunk.CHUNK_SIZE - index;
-        if (isWhitespace)
-            fCharDataHandler.processWhitespace(dataChunk.toCharArray(), index, nbytes);
-        else
-            fCharDataHandler.processCharacters(dataChunk.toCharArray(), index, nbytes);
-        count -= nbytes;
-
-        //
-        // Use each Chunk in turn until we are done.
-        //
-        do {
-            dataChunk = dataChunk.nextChunk();
-            if (dataChunk == null) {
-                throw new RuntimeException(new ImplementationMessages().createMessage(null, ImplementationMessages.INT_DCN, 0, null));
-            }
-            nbytes = count <= CharDataChunk.CHUNK_SIZE ? count : CharDataChunk.CHUNK_SIZE;
-            if (isWhitespace)
-                fCharDataHandler.processWhitespace(dataChunk.toCharArray(), 0, nbytes);
-            else
-                fCharDataHandler.processCharacters(dataChunk.toCharArray(), 0, nbytes);
-            count -= nbytes;
-        } while (count > 0);
-    }
-
-    /*
-     * Advance the reader's notion of where it is, moving on to the next chunk.
-     *
-     * @return The next character that will be processed.
-     * @exception java.lang.Exception
-     */
-    private int slowLoadNextChar() throws Exception {
-        fCallClearPreviousChunk = true;
-        if (fCurrentChunk.nextChunk() != null) {
-            fCurrentChunk = fCurrentChunk.nextChunk();
-            fCurrentIndex = 0;
-            fMostRecentData = fCurrentChunk.toCharArray();
-            return (fMostRecentChar = fMostRecentData[fCurrentIndex] & 0xFFFF);
-        } else {
-            fCurrentChunk = CharDataChunk.createChunk(fStringPool, fCurrentChunk);
-            return fillCurrentChunk();
-        }
-    }
-
-    /*
-     * Advance the reader's notion of where it is
-     *
-     * @return The next character that will be processed.
-     * @exception java.lang.Exception
-     */
-    private int loadNextChar() throws Exception {
-        fCurrentOffset++;
-        if (++fCurrentIndex == CharDataChunk.CHUNK_SIZE)
-            return slowLoadNextChar();
-        return (fMostRecentChar = fMostRecentData[fCurrentIndex] & 0xFFFF);
-    }
-
-    /*
-     * Would the reader be at end of file at a given offset?
-     *
-     * @param offset the offset to test for being at EOF
-     * @return true if being at offset would mean being at or beyond EOF
-     */
-    private boolean atEOF(int offset) {
-        return (offset > fLength);
-    }
-
-}
diff --git a/src/org/apache/xerces/readers/CharReader.java b/src/org/apache/xerces/readers/CharReader.java
deleted file mode 100644
index 7209cd2..0000000
--- a/src/org/apache/xerces/readers/CharReader.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.CharDataChunk;
-import org.apache.xerces.utils.StringPool;
-import java.io.Reader;
-
-/**
- * General purpose character stream reader.
- *
- * This class is used when the input source for the document entity is
- * specified using a character stream, when the input source is specified
- * using a byte stream with an explicit encoding, or when a recognizer
- * scans the encoding decl from the byte stream and chooses to use this
- * reader class for that encoding.  For the latter two cases, the byte
- * stream is wrapped in the appropriate InputStreamReader using the
- * desired encoding.
- *
- * @version
- */
-final class CharReader extends AbstractCharReader {
-    //
-    //
-    //
-    CharReader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter, boolean sendCharDataAsCharArray, Reader reader, StringPool stringPool) throws Exception {
-        super(entityHandler, errorReporter, sendCharDataAsCharArray, stringPool);
-        fCharacterStream = reader;
-        fillCurrentChunk();
-    }
-    //
-    //
-    //
-    private Reader fCharacterStream = null;
-    //
-    // When we fill a chunk there may be data that was read from the
-    // input stream that has not been "processed".  We need to save
-    // that data, and any in-progress state, between the calls to
-    // fillCurrentChunk() in these instance variables.  
-    //
-    private boolean fCheckOverflow = false;
-    private char[] fOverflow = null;
-    private int fOverflowOffset = 0;
-    private int fOverflowEnd = 0;
-    private int fOutputOffset = 0;
-    private boolean fSkipLinefeed = false;
-    //
-    //
-    //
-    protected int fillCurrentChunk() throws Exception {
-        //
-        // See if we can find a way to reuse the buffer that may have been returned
-        // with a recyled data chunk.
-        //
-        char[] recycledData = fCurrentChunk.toCharArray();
-        //
-        // If we have overflow from the last call, normalize from where
-        // we left off, copying into the front of the output buffer.
-        //
-        fOutputOffset = 0;
-        if (fCheckOverflow) {
-            //
-            // The fOverflowEnd should always be equal to CHUNK_SIZE, unless we hit
-            // EOF during the previous call.  Copy the remaining data to the front
-            // of the buffer and return it as the final chunk.
-            //
-            fMostRecentData = recycledData;
-            if (fOverflowEnd < CharDataChunk.CHUNK_SIZE) {
-                recycledData = null;
-                if (fOverflowEnd > 0) {
-                    if (fMostRecentData == null || fMostRecentData.length < 1 + fOverflowEnd - fOverflowOffset)
-                        fMostRecentData = new char[1 + fOverflowEnd - fOverflowOffset];
-                    copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset);
-                } else {
-                    if (fMostRecentData == null)
-                        fMostRecentData = new char[1];
-                }
-                fMostRecentData[fOutputOffset] = 0;
-                //
-                // Update our instance variables
-                //
-                fOverflow = null;
-                fLength += fOutputOffset;
-                fCurrentIndex = 0;
-                fCurrentChunk.setCharArray(fMostRecentData);
-                return (fMostRecentChar = fMostRecentData[0]);
-            }
-            if (fMostRecentData == null || fMostRecentData.length < CharDataChunk.CHUNK_SIZE)
-                fMostRecentData = new char[CharDataChunk.CHUNK_SIZE];
-            else
-                recycledData = null;
-            copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset);
-            fCheckOverflow = false;
-        } else {
-            if (fOverflow == null) {
-                fOverflow = recycledData;
-                if (fOverflow == null || fOverflow.length < CharDataChunk.CHUNK_SIZE)
-                    fOverflow = new char[CharDataChunk.CHUNK_SIZE];
-                else
-                    recycledData = null;
-            }
-            fMostRecentData = null;
-        }
-        while (true) {
-            fOverflowOffset = 0;
-            fOverflowEnd = 0;
-            int capacity = CharDataChunk.CHUNK_SIZE;
-            int result = 0;
-            do {
-                try {
-                    result = fCharacterStream.read(fOverflow, fOverflowEnd, capacity);
-                } catch (java.io.IOException ex) {
-                    result = -1;
-                }
-                if (result == -1) {
-                    //
-                    // We have reached the end of the stream.
-                    //
-                    fCharacterStream.close();
-                    fCharacterStream = null;
-                    if (fMostRecentData == null) {
-                        //
-                        // There is no previous output data, so we know that all of the
-                        // new input data will fit.
-                        //
-                        fMostRecentData = recycledData;
-                        if (fMostRecentData == null || fMostRecentData.length < 1 + fOverflowEnd)
-                            fMostRecentData = new char[1 + fOverflowEnd];
-                        else
-                            recycledData = null;
-                        copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset);
-                        fOverflow = null;
-                        fMostRecentData[fOutputOffset] = 0;
-                    } else {
-                        //
-                        // Copy the input data to the end of the output buffer.
-                        //
-                        boolean alldone = copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset);
-                        if (alldone) {
-                            if (fOverflowEnd == CharDataChunk.CHUNK_SIZE) {
-                                //
-                                // Special case - everything fit into the overflow buffer,
-                                // except that there is no room for the nul char we use to
-                                // indicate EOF.  Set the overflow buffer length to zero.
-                                // On the next call to this method, we will detect this
-                                // case and which we will handle above .
-                                //
-                                fCheckOverflow = true;
-                                fOverflowOffset = 0;
-                                fOverflowEnd = 0;
-                            } else {
-                                //
-                                // It all fit into the output buffer.
-                                //
-                                fOverflow = null;
-                                fMostRecentData[fOutputOffset] = 0;
-                            }
-                        } else {
-                            //
-                            // There is still input data left over, save the remaining data as
-                            // the overflow buffer for the next call.
-                            //
-                            fCheckOverflow = true;
-                        }
-                    }
-                    break;
-                }
-                if (result > 0) {
-                    fOverflowEnd += result;
-                    capacity -= result;
-                }
-            } while (capacity > 0);
-            //
-            //
-            //
-            if (result == -1)
-                break;
-            if (fMostRecentData != null) {
-                boolean alldone = copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset);
-                if (fOutputOffset == CharDataChunk.CHUNK_SIZE) {
-                    //
-                    // We filled the output buffer.
-                    //
-                    if (!alldone) {
-                        //
-                        // The input buffer will become the next overflow buffer.
-                        //
-                        fCheckOverflow = true;
-                    }
-                    break;
-                }
-            } else {
-                //
-                // Now normalize the end-of-line characters and see if we need to read more
-                // chars to fill up the buffer.
-                //
-                fMostRecentData = recycledData;
-                if (fMostRecentData == null || fMostRecentData.length < CharDataChunk.CHUNK_SIZE)
-                    fMostRecentData = new char[CharDataChunk.CHUNK_SIZE];
-                else
-                    recycledData = null;
-                copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset);
-                if (fOutputOffset == CharDataChunk.CHUNK_SIZE) {
-                    //
-                    // The output buffer is full.  We can return now.
-                    //
-                    break;
-                }
-            }
-            //
-            // We will need to get another intput buffer to be able to fill the
-            // overflow buffer completely.
-            //
-        }
-        //
-        // Update our instance variables
-        //
-        fLength += fOutputOffset;
-        fCurrentIndex = 0;
-        fCurrentChunk.setCharArray(fMostRecentData);
-        return (fMostRecentChar = fMostRecentData[0]);
-    }
-    //
-    // Copy and normalize chars from the overflow buffer into chars in our data buffer.
-    //
-    private boolean copyNormalize(char[] in, int inOffset, char[] out, int outOffset) throws Exception {
-        //
-        // Handle all edge cases before dropping into the inner loop.
-        //
-        int inEnd = fOverflowEnd;
-        int outEnd = out.length;
-        if (inOffset == inEnd)
-            return true;
-        char b = in[inOffset];
-        if (fSkipLinefeed) {
-            fSkipLinefeed = false;
-            if (b == 0x0A) {
-                if (++inOffset == inEnd)
-                    return exitNormalize(inOffset, outOffset, true);
-                b = in[inOffset];
-            }
-        }
-        while (outOffset < outEnd) {
-            //
-            // Find the longest run that we can guarantee will not exceed the
-            // bounds of the outer loop.
-            //
-            int inCount = inEnd - inOffset;
-            int outCount = outEnd - outOffset;
-            if (inCount > outCount)
-                inCount = outCount;
-            inOffset++;
-            while (true) {
-                while (b == 0x0D) {
-                    out[outOffset++] = 0x0A;
-                    if (inOffset == inEnd) {
-                        fSkipLinefeed = true;
-                        return exitNormalize(inOffset, outOffset, true);
-                    }
-                    b = in[inOffset];
-                    if (b == 0x0A) {
-                        if (++inOffset == inEnd)
-                            return exitNormalize(inOffset, outOffset, true);
-                        b = in[inOffset];
-                    }
-                    if (outOffset == outEnd)
-                        return exitNormalize(inOffset, outOffset, false);
-                    inCount = inEnd - inOffset;
-                    outCount = outEnd - outOffset;
-                    if (inCount > outCount)
-                        inCount = outCount;
-                    inOffset++;
-                }
-                while (true) {
-                    out[outOffset++] = b;
-                    if (--inCount == 0)
-                        break;
-                    b = in[inOffset++];
-                    if (b == 0x0D)
-                        break;
-                }
-                if (inCount == 0)
-                    break;
-            }
-            if (inOffset == inEnd)
-                break;
-        }
-        return exitNormalize(inOffset, outOffset, inOffset == inEnd);
-    }
-    //
-    //
-    //
-    private boolean exitNormalize(int inOffset, int outOffset, boolean result) {
-        fOverflowOffset = inOffset;
-        fOutputOffset = outOffset;
-        return result;
-    }
-}
diff --git a/src/org/apache/xerces/readers/DefaultEntityHandler.java b/src/org/apache/xerces/readers/DefaultEntityHandler.java
deleted file mode 100644
index 5047a0f..0000000
--- a/src/org/apache/xerces/readers/DefaultEntityHandler.java
+++ /dev/null
@@ -1,1399 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import java.io.FileNotFoundException;
-import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-import java.util.Stack;
-import java.util.Vector;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.ImplementationMessages;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.utils.URI;
-import org.apache.xerces.utils.XMLCharacterProperties;
-import org.apache.xerces.utils.XMLMessages;
-
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import org.xml.sax.helpers.LocatorImpl;
-
-/**
- * Default entity handler implementation.
- *
- * @version $Id$
- */
-public class DefaultEntityHandler 
-    implements XMLEntityHandler, XMLEntityHandler.DTDHandler {
-
-    public interface EventHandler {
-        public void startEntityReference(int entityName, int entityType, int entityContext) throws Exception;
-        public void endEntityReference(int entityName, int entityType, int entityContext) throws Exception;
-        public void sendEndOfInputNotifications(int entityName, boolean moreToFollow) throws Exception;
-        public void sendReaderChangeNotifications(XMLEntityHandler.EntityReader reader, int readerId) throws Exception;
-        public boolean externalEntityStandaloneCheck();
-        public boolean getValidating();
-    }
-
-    //
-    // Data
-    //
-    private class ReaderState {
-        XMLEntityHandler.EntityReader reader;
-        InputSource source;
-        int entityName;
-        int entityType;
-        int entityContext;
-        String publicId;
-        String systemId;
-        int readerId;
-        int depth;
-        ReaderState nextReaderState;
-    }
-    private ReaderState fReaderStateFreeList = null;
-    private StringPool fStringPool = null;
-    private EventHandler fEventHandler = null;
-    private XMLEntityHandler.CharDataHandler fCharDataHandler = null;
-    private XMLErrorReporter fErrorReporter = null;
-    private EntityResolver fResolver = null;
-    private EntityPool fEntityPool = null;
-    private EntityPool fParameterEntityPool = null;
-    private byte[] fEntityTypeStack = null;
-    private int[] fEntityNameStack = null;
-    private int fEntityStackDepth = 0;
-    private Stack fReaderStack = new Stack();
-    private XMLEntityHandler.EntityReader fReader = null;
-    private InputSource fSource = null;
-    private int fEntityName = -1;
-    private int fEntityType = -1;
-    private int fEntityContext = -1;
-    private String fPublicId = null;
-    private String fSystemId = null;
-    private int fReaderId = -1;
-    private int fReaderDepth = -1;
-    private int fNextReaderId = 0;
-    private NullReader fNullReader = null;
-    protected XMLEntityReaderFactory fReaderFactory = null;
-    private boolean fSendCharDataAsCharArray = false;
-
-    public DefaultEntityHandler(StringPool stringPool, XMLErrorReporter errorReporter) {
-        fStringPool = stringPool;
-        fErrorReporter = errorReporter;
-        fReaderFactory = new DefaultReaderFactory();
-        fEntityPool = new EntityPool(fStringPool, fErrorReporter, true);
-    }
-
-    public void setEventHandler(EventHandler eventHandler) {
-        fEventHandler = eventHandler;
-    }
-
-    public void setCharDataHandler(XMLEntityHandler.CharDataHandler charDataHandler) {
-        fCharDataHandler = charDataHandler;
-    }
-
-    public XMLEntityHandler.CharDataHandler getCharDataHandler() {
-        return fCharDataHandler;
-    }
-
-    /**
-     * Set char data processing preference.
-     */
-    public void setSendCharDataAsCharArray(boolean flag) {
-        fSendCharDataAsCharArray = flag;
-        fReaderFactory.setSendCharDataAsCharArray(fSendCharDataAsCharArray);
-    }
-
-    /**
-     * Set the reader factory.
-     */
-    public void setReaderFactory(XMLEntityReaderFactory readerFactory) {
-        fReaderFactory = readerFactory;
-        fReaderFactory.setSendCharDataAsCharArray(fSendCharDataAsCharArray);
-    }
-
-    /**
-     * Reset the entity handler.
-     */
-    public void reset(StringPool stringPool) {
-        fStringPool = stringPool;
-        fEntityPool.reset(fStringPool);
-        fParameterEntityPool = null;
-        fReaderStack.removeAllElements();
-        fEntityStackDepth = 0;
-        fReader = null;
-        fSource = null;
-        fEntityName = -1;
-        fEntityType = -1;
-        fEntityContext = -1;
-        fPublicId = null;
-        fSystemId = null;
-        fReaderId = -1;
-        fReaderDepth = -1;
-        fNextReaderId = 0;
-    }
-
-    /**
-     *
-     */
-    public void setAllowJavaEncodings(boolean flag) {
-        fReaderFactory.setAllowJavaEncodingName(flag);
-    }
-    /**
-     *
-     */
-    public boolean getAllowJavaEncodings() {
-        return fReaderFactory.getAllowJavaEncodingName();
-    }
-
-    //
-    //
-    //
-    public int addInternalPEDecl(int name, int value, boolean isExternal) throws Exception {
-        if (fParameterEntityPool == null)
-            fParameterEntityPool = new EntityPool(fStringPool, fErrorReporter, false);
-        int entityHandle = fParameterEntityPool.addEntityDecl(name, value, -1, -1, -1, -1, isExternal);
-        return entityHandle;
-    }
-    public int addExternalPEDecl(int name, int publicId, int systemId, boolean isExternal) throws Exception {
-        if (fParameterEntityPool == null)
-            fParameterEntityPool = new EntityPool(fStringPool, fErrorReporter, false);
-        int entityHandle = fParameterEntityPool.addEntityDecl(name, -1, publicId, systemId, fStringPool.addSymbol(fSystemId), -1, isExternal);
-        return entityHandle;
-    }
-    public int addInternalEntityDecl(int name, int value, boolean isExternal) throws Exception {
-        int entityHandle = fEntityPool.addEntityDecl(name, value, -1, -1, -1, -1, isExternal);
-        return entityHandle;
-    }
-    public int addExternalEntityDecl(int name, int publicId, int systemId, boolean isExternal) throws Exception {
-        int entityHandle = fEntityPool.addEntityDecl(name, -1, publicId, systemId, fStringPool.addSymbol(fSystemId), -1, isExternal);
-        return entityHandle;
-    }
-    public int addUnparsedEntityDecl(int name, int publicId, int systemId, int notationName, boolean isExternal) throws Exception {
-        int entityHandle = fEntityPool.addEntityDecl(name, -1, publicId, systemId, fStringPool.addSymbol(fSystemId), notationName, isExternal);
-        if (!fEntityPool.isNotationDeclared(notationName)) {
-            Object[] args = { fStringPool.toString(name),
-                              fStringPool.toString(notationName) };
-            fEntityPool.addRequiredNotation(notationName,
-                                            fErrorReporter.getLocator(),
-                                            XMLMessages.MSG_NOTATION_NOT_DECLARED_FOR_UNPARSED_ENTITYDECL,
-                                            XMLMessages.VC_NOTATION_DECLARED,
-                                            args);
-        }
-        return entityHandle;
-    }
-    public int addNotationDecl(int notationName, int publicId, int systemId, boolean isExternal) throws Exception {
-        int notationHandle = fEntityPool.addNotationDecl(notationName, publicId, systemId, fStringPool.addSymbol(fSystemId), isExternal);
-        return notationHandle;
-    }
-    public boolean isUnparsedEntity(int entityName) {
-        int entityHandle = fEntityPool.lookupEntity(entityName);
-        return (entityHandle != -1 && fEntityPool.isUnparsedEntity(entityHandle));
-    }
-    public boolean isNotationDeclared(int notationName) {
-        return fEntityPool.isNotationDeclared(notationName);
-    }
-    public void addRequiredNotation(int notationName, Locator locator, int majorCode, int minorCode, Object[] args) {
-        fEntityPool.addRequiredNotation(notationName, locator, majorCode, minorCode, args);
-    }
-    public void checkRequiredNotations() throws Exception {
-        fEntityPool.checkRequiredNotations();
-    }
-
-    protected int lookupEntity(int entityNameIndex) {
-        int entityIndex = fEntityPool.lookupEntity(entityNameIndex);
-        return entityIndex;
-    }
-    private void reportRecoverableXMLError(int majorCode, int minorCode, int stringIndex1) throws Exception {
-        Object[] args = { fStringPool.toString(stringIndex1) };
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-    }
-    public boolean externalReferenceInContent(int entityHandle) throws Exception {
-        boolean external = fEntityPool.isExternalEntity(entityHandle);
-        if (fEventHandler.externalEntityStandaloneCheck()) {
-            if (external) {
-                reportRecoverableXMLError(XMLMessages.MSG_EXTERNAL_ENTITY_NOT_PERMITTED,
-                                          XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
-                                          fEntityName);
-            } else if (fEntityPool.getEntityDeclIsExternal(entityHandle)) {
-                reportRecoverableXMLError(XMLMessages.MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE,
-                                          XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
-                                          fEntityName);
-            }
-        }
-        return external;
-    }
-    protected int valueOfReferenceInAttValue(int entityHandle) throws Exception {
-        if (fEventHandler.externalEntityStandaloneCheck() && fEntityPool.getEntityDeclIsExternal(entityHandle)) {
-            reportRecoverableXMLError(XMLMessages.MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE,
-                                      XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
-                                      fEntityName);
-        }
-        int entityValue = fEntityPool.getEntityValue(entityHandle);
-        return entityValue;
-    }
-    protected boolean isExternalEntity(int entityHandle) {
-        boolean external = fEntityPool.isExternalEntity(entityHandle);
-        return external;
-    }
-    protected int getEntityValue(int entityHandle) {
-        int value = fEntityPool.getEntityValue(entityHandle);
-        return value;
-    }
-    protected String getPublicIdOfEntity(int entityHandle) {
-        int publicId = fEntityPool.getPublicId(entityHandle);
-        return fStringPool.toString(publicId);
-    }
-    protected String getSystemIdOfEntity(int entityHandle) {
-        int systemId = fEntityPool.getSystemId(entityHandle);
-        return fStringPool.toString(systemId);
-    }
-    protected int lookupParameterEntity(int peName) throws Exception {
-        int entityHandle = -1;
-        if (fParameterEntityPool != null)
-            entityHandle = fParameterEntityPool.lookupEntity(peName);
-        return entityHandle;
-    }
-    protected boolean isExternalParameterEntity(int peIndex) {
-        boolean external = fParameterEntityPool.isExternalEntity(peIndex);
-        return external;
-    }
-    protected int getParameterEntityValue(int peIndex) {
-        int value = fParameterEntityPool.getEntityValue(peIndex);
-        return value;
-    }
-    protected String getPublicIdOfParameterEntity(int peIndex) {
-        int publicId = fParameterEntityPool.getPublicId(peIndex);
-        return fStringPool.toString(publicId);
-    }
-    protected String getSystemIdOfParameterEntity(int peIndex) {
-        int systemId = fParameterEntityPool.getSystemId(peIndex);
-        return fStringPool.toString(systemId);
-    }
-
-    /**
-     * get the Entity reader.
-     */
-    public XMLEntityHandler.EntityReader getEntityReader() {
-        return fReader;
-    }
-
-    /**
-     * Adds a recognizer.
-     *
-     * @param recognizer The XML recognizer to add.
-     */
-    public void addRecognizer(XMLDeclRecognizer recognizer) {
-        fReaderFactory.addRecognizer(recognizer);
-    }
-
-    /**
-     * Sets the resolver used to resolve external entities. The EntityResolver
-     * interface supports resolution of public and system identifiers.
-     *
-     * @param resolver The new entity resolver. Passing a null value will
-     *                 uninstall the currently installed resolver.
-     */
-    public void setEntityResolver(EntityResolver resolver) {
-        fResolver = resolver;
-    }
-
-    /**
-     * Gets the resolver used to resolve external entities. The EntityResolver
-     * interface supports resolution of public and system identifiers.
-     *
-     * @return The current entity resolver.
-     */
-    public EntityResolver getEntityResolver() {
-        return fResolver;
-    }
-
-    /**
-     * Expands a system id and returns the system id as a URI, if
-     * it can be expanded. A return value of null means that the
-     * identifier is already expanded. An exception thrown
-     * indicates a failure to expand the id.
-     *
-     * @param systemId The systemId to be expanded.
-     *
-     * @return Returns the URI string representing the expanded system
-     *         identifier. A null value indicates that the given
-     *         system identifier is already expanded.
-     *
-     */
-    public String expandSystemId(String systemId) {
-        return expandSystemId(systemId, fSystemId);
-    }
-    private String expandSystemId(String systemId, String currentSystemId) {
-        String id = systemId;
-
-        // check for bad parameters id
-        if (id == null || id.length() == 0) {
-            return systemId;
-        }
-
-        // if id already expanded, return
-        try {
-            URI uri = new URI(id);
-            if (uri != null) {
-                return systemId;
-            }
-        }
-        catch (URI.MalformedURIException e) {
-            // continue on...
-        }
-
-        // normalize id
-        id = fixURI(id);
-
-        // normalize base
-        URI base = null;
-        URI uri = null;
-        try {
-            if (currentSystemId == null) {
-                String dir;
-                try {
-                    dir = fixURI(System.getProperty("user.dir"));
-                }
-                catch (SecurityException se) {
-                    dir = "";
-                }
-                if (!dir.endsWith("/")) {
-                    dir = dir + "/";
-                }
-                base = new URI("file", "", dir, null, null);
-            }
-            else {
-                base = new URI(currentSystemId);
-            }
-
-            // expand id
-            uri = new URI(base, id);
-        }
-        catch (Exception e) {
-            // let it go through
-        }
-        if (uri == null) {
-            return systemId;
-        }
-        return uri.toString();
-    }
-
-    //
-    // Private methods
-    //
-
-    /**
-     * Fixes a platform dependent filename to standard URI form.
-     *
-     * @param str The string to fix.
-     *
-     * @return Returns the fixed URI string.
-     */
-    private static String fixURI(String str) {
-
-        // handle platform dependent strings
-        str = str.replace(java.io.File.separatorChar, '/');
-
-        // Windows fix
-        if (str.length() >= 2) {
-            char ch1 = str.charAt(1);
-            if (ch1 == ':') {
-                char ch0 = Character.toUpperCase(str.charAt(0));
-                if (ch0 >= 'A' && ch0 <= 'Z') {
-                    str = "/" + str;
-                }
-            }
-        }
-
-        // done
-        return str;
-    }
-
-    public boolean startReadingFromDocument(InputSource source) throws Exception {
-        pushEntity(false, -2); // Document Entity
-        fSystemId = null;
-        pushNullReader();
-        fEntityName = -2; // Document Entity
-        fEntityType = ENTITYTYPE_DOCUMENT;
-        fEntityContext = ENTITYREF_DOCUMENT;
-        fReaderDepth = 0;
-        fReaderId = fNextReaderId++;
-        fPublicId = source.getPublicId();
-        fSystemId = source.getSystemId();
-        fEventHandler.startEntityReference(fEntityName, fEntityType, fEntityContext);
-        fSystemId = expandSystemId(fSystemId, null);
-        fSource = source;
-        boolean xmlDecl = true; // xmlDecl if true, textDecl if false
-        try {
-            fReader = fReaderFactory.createReader(this, fErrorReporter, source, fSystemId, xmlDecl, fStringPool);
-        } catch (MalformedURLException mu) {
-            String errorSystemId = fSystemId;
-            fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
-            popReader();
-            popEntity();
-            fReader = null;
-            Object[] args = { errorSystemId };
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                        ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
-                                        ImplementationMessages.IO0,
-                                        0,
-                                        args,
-                                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-        } catch (FileNotFoundException fnf) {
-            String errorSystemId = fSystemId;
-            fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
-            popReader();
-            popEntity();
-            fReader = null;
-            Object[] args = { errorSystemId };
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                        ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
-                                        ImplementationMessages.IO0,
-                                        0,
-                                        args,
-                                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-        } catch (UnsupportedEncodingException uee) {
-            fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
-            popReader();
-            popEntity();
-            fReader = null;
-            String encoding = uee.getMessage();
-            if (encoding == null) {
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_ENCODING_REQUIRED,
-                                           XMLMessages.P81_REQUIRED,
-                                           null,
-                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            } else if (!XMLCharacterProperties.validEncName(encoding)) {
-                Object[] args = { encoding };
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_ENCODINGDECL_INVALID,
-                                           XMLMessages.P81_INVALID_VALUE,
-                                           args,
-                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            } else {
-                Object[] args = { encoding };
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_ENCODING_NOT_SUPPORTED,
-                                           XMLMessages.P81_NOT_SUPPORTED,
-                                           args,
-                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            }
-        }
-        fEventHandler.sendReaderChangeNotifications(fReader, fReaderId);
-        return fReader != null;
-    }
-    /**
-     * start reading from an external DTD subset
-     */
-    public void startReadingFromExternalSubset(String publicId, String systemId, int readerDepth) throws Exception {
-        pushEntity(true, -1);
-        pushReader();
-        pushNullReader();
-        fEntityName = -1; // External Subset
-        fEntityType = ENTITYTYPE_EXTERNAL_SUBSET;
-        fEntityContext = ENTITYREF_EXTERNAL_SUBSET;
-        fReaderDepth = readerDepth;
-        fReaderId = fNextReaderId++;
-        fPublicId = publicId;
-        fSystemId = systemId;
-        startReadingFromExternalEntity(false, -1);
-    }
-    /**
-     * stop reading from an external DTD subset
-     */
-    public void stopReadingFromExternalSubset() throws Exception {
-        if (!(fReader instanceof NullReader))
-            throw new RuntimeException("FWK004 cannot happen 18"+"\n18");
-        popReader();
-        fEventHandler.sendReaderChangeNotifications(fReader, fReaderId);
-    }
-
-    /**
-     * start reading from an external entity
-     */
-    public boolean startReadingFromEntity(int entityName, int readerDepth, int context) throws Exception {
-        if (context > XMLEntityHandler.ENTITYREF_IN_CONTENT)
-            return startReadingFromParameterEntity(entityName, readerDepth, context);
-        int entityHandle = lookupEntity(entityName);
-        if (entityHandle < 0) {
-            int minorCode = XMLMessages.VC_ENTITY_DECLARED;
-            int errorType = XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR;
-            // REVISIT - the following test in insufficient...
-            if (fEntityContext == ENTITYREF_DOCUMENT || fEntityContext == ENTITYREF_IN_ATTVALUE) {
-                minorCode = XMLMessages.WFC_ENTITY_DECLARED;
-                errorType = XMLErrorReporter.ERRORTYPE_FATAL_ERROR;
-            } else if (!fEventHandler.getValidating()) {
-                return false;
-            }
-            Object[] args = { fStringPool.toString(entityName) };
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                       XMLMessages.XML_DOMAIN,
-                                       XMLMessages.MSG_ENTITY_NOT_DECLARED,
-                                       minorCode,
-                                       args,
-                                       errorType);
-            return false;
-        }
-        if (context == ENTITYREF_IN_CONTENT) {
-            if (fEntityPool.isUnparsedEntity(entityHandle)) {
-                Object[] args = { fStringPool.toString(entityName) };
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_REFERENCE_TO_UNPARSED_ENTITY,
-                                           XMLMessages.WFC_PARSED_ENTITY,
-                                           args,
-                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-                return false;
-            }
-        } else {
-            if (isExternalEntity(entityHandle)) {
-                Object[] args = { fStringPool.toString(entityName) };
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_REFERENCE_TO_EXTERNAL_ENTITY,
-                                           XMLMessages.WFC_NO_EXTERNAL_ENTITY_REFERENCES,
-                                           args,
-                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-                return false;
-            }
-        }
-        if (!pushEntity(false, entityName)) {
-            Object[] args = { fStringPool.toString(entityName),
-                              entityReferencePath(false, entityName) };
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                       XMLMessages.XML_DOMAIN,
-                                       XMLMessages.MSG_RECURSIVE_REFERENCE,
-                                       XMLMessages.WFC_NO_RECURSION,
-                                       args,
-                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            return false;
-        }
-        pushReader();
-        fEntityName = entityName;
-        fEntityContext = context;
-        fReaderDepth = readerDepth;
-        fReaderId = fNextReaderId++;
-        if (context != ENTITYREF_IN_CONTENT || !externalReferenceInContent(entityHandle)) {
-            fEntityType = ENTITYTYPE_INTERNAL;
-            fPublicId = null/*"Internal Entity: " + fStringPool.toString(entityName)*/;
-            fSystemId = fSystemId; // keep expandSystemId happy
-            int value = -1;
-            if (context == ENTITYREF_IN_CONTENT || context == ENTITYREF_IN_DEFAULTATTVALUE)
-                value = getEntityValue(entityHandle);
-            else
-                value = valueOfReferenceInAttValue(entityHandle);
-            startReadingFromInternalEntity(value, false);
-            return false;
-        }
-        fEntityType = ENTITYTYPE_EXTERNAL;
-        fPublicId = getPublicIdOfEntity(entityHandle);
-        fSystemId = getSystemIdOfEntity(entityHandle);
-        return startReadingFromExternalEntity(true, entityHandle);
-    }
-    private boolean startReadingFromParameterEntity(int peName, int readerDepth, int context) throws Exception {
-        int entityHandle = lookupParameterEntity(peName);
-        if (entityHandle == -1) {
-            // strange... this is a VC, not a WFC...
-            if (fEventHandler.getValidating()) {
-                reportRecoverableXMLError(XMLMessages.MSG_ENTITY_NOT_DECLARED,
-                                          XMLMessages.VC_ENTITY_DECLARED,
-                                          peName);
-            }
-            return false;
-        }
-        if (!pushEntity(true, peName)) {
-            Object[] args = { fStringPool.toString(peName),
-                              entityReferencePath(true, peName) };
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                       XMLMessages.XML_DOMAIN,
-                                       XMLMessages.MSG_RECURSIVE_PEREFERENCE,
-                                       XMLMessages.WFC_NO_RECURSION,
-                                       args,
-                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            return false;
-        }
-        pushReader();
-        fEntityName = peName;
-        fEntityContext = context;
-        fReaderDepth = readerDepth;
-        fReaderId = fNextReaderId++;
-        if (!isExternalParameterEntity(entityHandle)) {
-            fEntityType = ENTITYTYPE_INTERNAL_PE;
-            fPublicId = null/*"Internal Entity: %" + fStringPool.toString(peName)*/;
-            fSystemId = fSystemId; // keep expandSystemId happy
-            int value = getParameterEntityValue(entityHandle);
-            startReadingFromInternalEntity(value, fEntityContext == ENTITYREF_IN_ENTITYVALUE ? false : true);
-            return false;
-        }
-        fEntityType = ENTITYTYPE_EXTERNAL_PE;
-        fPublicId = getPublicIdOfParameterEntity(entityHandle);
-        fSystemId = getSystemIdOfParameterEntity(entityHandle);
-        return startReadingFromExternalEntity(true, entityHandle);
-    }
-    private void startReadingFromInternalEntity(int value, boolean addSpaces) throws Exception {
-        if (fEntityContext == ENTITYREF_IN_ENTITYVALUE) {
-            //
-            // REVISIT - consider optimizing the case where the entire entity value
-            // consists of a single reference to a parameter entity and do not append
-            // the value to fLiteralData again, but re-use the offset/length of the
-            // referenced entity for the value of this entity.
-            //
-        }
-        fSource = null;
-        fEventHandler.startEntityReference(fEntityName, fEntityType, fEntityContext);
-        fReader = fReaderFactory.createStringReader(this, fErrorReporter, fSendCharDataAsCharArray, getLineNumber(), getColumnNumber(), value, fStringPool, addSpaces); // REVISIT - string reader needs better location support
-        fEventHandler.sendReaderChangeNotifications(fReader, fReaderId);
-    }
-    private boolean startReadingFromExternalEntity(boolean checkForTextDecl, int entityHandle) throws Exception {
-        if (fEntityContext == ENTITYREF_IN_ENTITYVALUE) {
-            //
-            // REVISIT - Can we get the spec changed ?
-            // There is a perverse edge case to handle here...  We have a reference
-            // to an external PE within a literal EntityValue.  For the PE to be
-            // well-formed, it must match the extPE production, but the code that
-            // appends the replacement text to the entity value is in no position
-            // to do a complete well-formedness check !!
-            //
-        }
-        if (fEntityContext == ENTITYREF_IN_DTD_WITHIN_MARKUP) {
-            //
-            // REVISIT - Can we get the spec changed ?
-            // There is a perverse edge case to handle here...  We have a reference
-            // to an external PE within markup.  For the PE to be well-formed, it
-            // must match the extPE production, which is probably not going to be
-            // very useful expanded in the middle of a markup declaration.  The
-            // problem is that an empty file, a file containing just whitespace or
-            // another PE that is just empty or whitespace, matches extPE !!
-            //
-        }
-        fEventHandler.startEntityReference(fEntityName, fEntityType, fEntityContext);
-        String baseSystemId = null;
-        if (entityHandle != -1) {
-            if (fEntityType == ENTITYTYPE_EXTERNAL_PE)
-                baseSystemId =
-                    fParameterEntityPool.getBaseSystemId(entityHandle);
-            else
-                baseSystemId = fEntityPool.getBaseSystemId(entityHandle);
-        }
-        if (baseSystemId == null) {
-            ReaderState rs = (ReaderState) fReaderStack.peek();
-            baseSystemId = rs.systemId;
-        }
-        fSystemId = expandSystemId(fSystemId, baseSystemId);
-        fSource = fResolver == null ? null : fResolver.resolveEntity(fPublicId, fSystemId);
-        if (fSource == null) {
-            fSource = new InputSource(fSystemId);
-            if (fPublicId != null)
-                fSource.setPublicId(fPublicId);
-        } else {
-            if (fSource.getSystemId() != null) {
-                fSystemId =
-                    expandSystemId(fSource.getSystemId(), baseSystemId);
-            }
-            if (fSource.getPublicId() != null) {
-                fPublicId = fSource.getPublicId();
-            }
-        }
-
-        boolean textDecl = false; // xmlDecl if true, textDecl if false
-        try {
-            fReader = fReaderFactory.createReader(this, fErrorReporter, fSource, fSystemId, textDecl, fStringPool);
-        } catch (MalformedURLException mu) {
-            String errorSystemId = fSystemId;
-            fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
-            popReader();
-            popEntity();
-            fReader = null;
-            Object[] args = { errorSystemId };
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                        ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
-                                        ImplementationMessages.IO0,
-                                        0,
-                                        args,
-                                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-        } catch (FileNotFoundException fnf) {
-            String errorSystemId = fSystemId;
-            fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
-            popReader();
-            popEntity();
-            fReader = null;
-            Object[] args = { errorSystemId };
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                        ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
-                                        ImplementationMessages.IO0,
-                                        0,
-                                        args,
-                                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-        } catch (UnsupportedEncodingException uee) {
-            fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
-            popReader();
-            popEntity();
-            fReader = null;
-            String encoding = uee.getMessage();
-            if (encoding == null) {
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_ENCODING_REQUIRED,
-                                           XMLMessages.P81_REQUIRED,
-                                           null,
-                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            } else if (!XMLCharacterProperties.validEncName(encoding)) {
-                Object[] args = { encoding };
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_ENCODINGDECL_INVALID,
-                                           XMLMessages.P81_INVALID_VALUE,
-                                           args,
-                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            } else {
-                Object[] args = { encoding };
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_ENCODING_NOT_SUPPORTED,
-                                           XMLMessages.P81_NOT_SUPPORTED,
-                                           args,
-                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            }
-        }
-        if (fReader == null || !checkForTextDecl) {
-            fEventHandler.sendReaderChangeNotifications(fReader, fReaderId);
-            return false;
-        }
-        int readerId = fReaderId;
-        fEventHandler.sendReaderChangeNotifications(fReader, fReaderId);
-        boolean parseTextDecl = fReader.lookingAtChar('<', false);
-        if (readerId != fReaderId)
-            parseTextDecl = false;
-        return parseTextDecl;
-    }
-
-    //
-    // reader stack
-    //
-    private void pushNullReader() {
-        ReaderState rs = fReaderStateFreeList;
-        if (rs == null)
-            rs = new ReaderState();
-        else
-            fReaderStateFreeList = rs.nextReaderState;
-        if (fNullReader == null)
-            fNullReader = new NullReader();
-        rs.reader = fNullReader;
-        rs.source = null;
-        rs.entityName = -1; // Null Entity
-        rs.entityType = -1; // Null Entity
-        rs.entityContext = -1; // Null Entity
-        rs.publicId = "Null Entity";
-        rs.systemId = fSystemId;
-        rs.readerId = fNextReaderId++;
-        rs.depth = -1;
-        rs.nextReaderState = null;
-        fReaderStack.push(rs);
-    }
-    private void pushReader() {
-        ReaderState rs = fReaderStateFreeList;
-        if (rs == null)
-            rs = new ReaderState();
-        else
-            fReaderStateFreeList = rs.nextReaderState;
-        rs.reader = fReader;
-        rs.source = fSource;
-        rs.entityName = fEntityName;
-        rs.entityType = fEntityType;
-        rs.entityContext = fEntityContext;
-        rs.publicId = fPublicId;
-        rs.systemId = fSystemId;
-        rs.readerId = fReaderId;
-        rs.depth = fReaderDepth;
-        rs.nextReaderState = null;
-        fReaderStack.push(rs);
-    }
-    private void popReader() {
-        if (fReaderStack.empty())
-            throw new RuntimeException("FWK004 cannot happen 19"+"\n19");
-        ReaderState rs = (ReaderState) fReaderStack.pop();
-        fReader = rs.reader;
-        fSource = rs.source;
-        fEntityName = rs.entityName;
-        fEntityType = rs.entityType;
-        fEntityContext = rs.entityContext;
-        fPublicId = rs.publicId;
-        fSystemId = rs.systemId;
-        fReaderId = rs.readerId;
-        fReaderDepth = rs.depth;
-        rs.nextReaderState = fReaderStateFreeList;
-        fReaderStateFreeList = rs;
-    }
-
-    /**
-     * start an entity declaration
-     */
-    public boolean startEntityDecl(boolean isPE, int entityName) throws Exception {
-        if (!pushEntity(isPE, entityName)) {
-            int majorCode = isPE ? XMLMessages.MSG_RECURSIVE_PEREFERENCE : XMLMessages.MSG_RECURSIVE_REFERENCE;
-            Object[] args = { fStringPool.toString(entityName),
-                              entityReferencePath(isPE, entityName) };
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                       XMLMessages.XML_DOMAIN,
-                                       majorCode,
-                                       XMLMessages.WFC_NO_RECURSION,
-                                       args,
-                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            return false;
-        }
-        return true;
-    }
-    /**
-     * end an entity declaration
-     */
-    public void endEntityDecl() throws Exception {
-        popEntity();
-    }
-    //
-    // entity stack
-    //
-    private boolean pushEntity(boolean isPE, int entityName) throws Exception {
-        if (entityName >= 0) {
-            for (int i = 0; i < fEntityStackDepth; i++) {
-                if (fEntityNameStack[i] == entityName && fEntityTypeStack[i] == (isPE ? 1 : 0)) {
-                    return false;
-                }
-            }
-        }
-        if (fEntityTypeStack == null) {
-            fEntityTypeStack = new byte[8];
-            fEntityNameStack = new int[8];
-        } else if (fEntityStackDepth == fEntityTypeStack.length) {
-            byte[] newTypeStack = new byte[fEntityStackDepth * 2];
-            System.arraycopy(fEntityTypeStack, 0, newTypeStack, 0, fEntityStackDepth);
-            fEntityTypeStack = newTypeStack;
-            int[] newNameStack = new int[fEntityStackDepth * 2];
-            System.arraycopy(fEntityNameStack, 0, newNameStack, 0, fEntityStackDepth);
-            fEntityNameStack = newNameStack;
-        }
-        fEntityTypeStack[fEntityStackDepth] = (byte)(isPE ? 1 : 0);
-        fEntityNameStack[fEntityStackDepth] = entityName;
-        fEntityStackDepth++;
-        return true;
-    }
-    private String entityReferencePath(boolean isPE, int entityName) {
-        StringBuffer sb = new StringBuffer();
-        sb.append("(top-level)");
-        for (int i = 0; i < fEntityStackDepth; i++) {
-            if (fEntityNameStack[i] >= 0) {
-                sb.append('-');
-                sb.append(fEntityTypeStack[i] == 1 ? '%' : '&');
-                sb.append(fStringPool.toString(fEntityNameStack[i]));
-                sb.append(';');
-            }
-        }
-        sb.append('-');
-        sb.append(isPE ? '%' : '&');
-        sb.append(fStringPool.toString(entityName));
-        sb.append(';');
-        return sb.toString();
-    }
-    private void popEntity() throws Exception {
-        fEntityStackDepth--;
-    }
-
-    //
-    //
-    //
-    /**
-     * This method is provided for scanner implementations.
-     */
-    public int getReaderId() {
-        return fReaderId;
-    }
-    /**
-     * This method is provided for scanner implementations.
-     */
-    public void setReaderDepth(int depth) {
-        fReaderDepth = depth;
-    }
-    /**
-     * This method is provided for scanner implementations.
-     */
-    public int getReaderDepth() {
-        return fReaderDepth;
-    }
-    /**
-     * Return the public identifier of the <code>InputSource</code> that we are processing.
-     *
-     * @return The public identifier, or null if not provided.
-     */
-    public String getPublicId() {
-        return fPublicId;
-    }
-    /**
-     * Return the system identifier of the <code>InputSource</code> that we are processing.
-     *
-     * @return The system identifier, or null if not provided.
-     */
-    public String getSystemId() {
-        return fSystemId;
-    }
-    /**
-     * Return the line number of the current position within the document that we are processing.
-     *
-     * @return The current line number.
-     */
-    public int getLineNumber() {
-        return fReader == null ? 0 : fReader.getLineNumber();
-    }
-    /**
-     * Return the column number of the current position within the document that we are processing.
-     *
-     * @return The current column number.
-     */
-    public int getColumnNumber() {
-        return fReader == null ? 0 : fReader.getColumnNumber();
-    }
-    /**
-     * This method is called by the reader subclasses at the
-     * end of input, and also by the scanner directly to force
-     * a reader change during error recovery.
-     */
-    public XMLEntityHandler.EntityReader changeReaders() throws Exception {
-        fEventHandler.sendEndOfInputNotifications(fEntityName, fReaderStack.size() > 1);
-        fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext);
-        popReader();
-        fEventHandler.sendReaderChangeNotifications(fReader, fReaderId);
-        popEntity();
-        return fReader;
-    }
-
-    //
-    // We use the null reader after we have reached the
-    // end of input for the document or external subset.
-    //
-    private final class NullReader implements XMLEntityHandler.EntityReader {
-        //
-        //
-        //
-        public NullReader() {
-        }
-        public int currentOffset() {
-            return -1;
-        }
-        public int getLineNumber() {
-            return -1;
-        }
-        public int getColumnNumber() {
-            return -1;
-        }
-        public void setInCDSect(boolean inCDSect) {
-        }
-        public boolean getInCDSect() {
-            return false;
-        }
-        public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length) {
-        }
-        public int addString(int offset, int length) {
-            return -1;
-        }
-        public int addSymbol(int offset, int length) {
-            return -1;
-        }
-        public boolean lookingAtChar(char ch, boolean skipPastChar) {
-            return false;
-        }
-        public boolean lookingAtValidChar(boolean skipPastChar) {
-            return false;
-        }
-        public boolean lookingAtSpace(boolean skipPastChar) {
-            return false;
-        }
-        public void skipToChar(char ch) {
-        }
-        public void skipPastSpaces() {
-        }
-        public void skipPastName(char fastcheck) {
-        }
-        public void skipPastNmtoken(char fastcheck) {
-        }
-        public boolean skippedString(char[] s) {
-            return false;
-        }
-        public int scanInvalidChar() {
-            return -1;
-        }
-        public int scanCharRef(boolean hex) {
-            return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-        }
-        public int scanStringLiteral() {
-            return XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED;
-        }
-        public int scanAttValue(char qchar, boolean asSymbol) {
-            return XMLEntityHandler.ATTVALUE_RESULT_INVALID_CHAR;
-        }
-        public int scanEntityValue(int qchar, boolean createString) {
-            return XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR;
-        }
-        public boolean scanExpectedName(char fastcheck, StringPool.CharArrayRange expectedName) {
-            return false;
-        }
-        public void scanQName(char fastcheck, QName qname) {
-            qname.clear();
-        }
-        public int scanName(char fastcheck) {
-            return -1;
-        }
-        public int scanContent(QName element) throws Exception {
-            return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-        }
-    }
-
-    //
-    // Entity Pool
-    //
-
-    //
-    // Chunk size constants
-    //
-    static final int CHUNK_SHIFT = 5;           // 2^5 = 32
-    static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
-    static final int CHUNK_MASK = CHUNK_SIZE - 1;
-    static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT));   // 2^10 = 1k
-
-public final class EntityPool {
-    //
-    // Constants
-    //
-
-    //
-    // Instance variables
-    //
-    private StringPool fStringPool = null;
-    private XMLErrorReporter fErrorReporter = null;
-    //
-    // We store both EntityDecl and NotationDecl instances in this pool.
-    // A NotationDecl has an fName field of -1.  The fNotationDeclHead
-    // index is -1 if the NotationDecl list is empty, otherwise it contains
-    // the index of the the last NotationDecl in the list and the fValue
-    // field contains the index of the previous NotationDecl, or -1 when at
-    // the end of the list.
-    //
-    private int fEntityCount = 0;
-    private int[][] fName = new int[INITIAL_CHUNK_COUNT][];
-    private int[][] fValue = new int[INITIAL_CHUNK_COUNT][];
-    private int[][] fPublicId = new int[INITIAL_CHUNK_COUNT][];
-    private int[][] fSystemId = new int[INITIAL_CHUNK_COUNT][];
-    private int[][] fBaseSystemId = new int[INITIAL_CHUNK_COUNT][];
-    private int[][] fNotationName = new int[INITIAL_CHUNK_COUNT][];
-    private byte[][] fDeclIsExternal = new byte[INITIAL_CHUNK_COUNT][];
-    private int fNotationListHead = -1;
-    private boolean fCreateStandardEntities = false;
-    private Vector fRequiredNotations = null;
-    //
-    // Constructor
-    //
-    public EntityPool(StringPool stringPool, XMLErrorReporter errorReporter, boolean createStandardEntities) {
-        fStringPool = stringPool;
-        fErrorReporter = errorReporter;
-        fCreateStandardEntities = createStandardEntities;
-        if (fCreateStandardEntities) {
-            createInternalEntity("lt", "&#60;");
-            createInternalEntity("gt", ">");
-            createInternalEntity("amp", "&#38;");
-            createInternalEntity("apos", "\'");
-            createInternalEntity("quot", "\"");
-        }
-    }
-    //
-    //
-    //
-    public void reset(StringPool stringPool) {
-        fStringPool = stringPool;
-        fEntityCount = 0;
-        fNotationListHead = -1;
-        if (fRequiredNotations != null)
-            fRequiredNotations.removeAllElements();
-        if (fCreateStandardEntities) {
-            createInternalEntity("lt", "&#60;");
-            createInternalEntity("gt", ">");
-            createInternalEntity("amp", "&#38;");
-            createInternalEntity("apos", "\'");
-            createInternalEntity("quot", "\"");
-        }
-    }
-    //
-    //
-    //
-    private void createInternalEntity(String name, String value) {
-        int chunk = fEntityCount >> CHUNK_SHIFT;
-        int index = fEntityCount & CHUNK_MASK;
-        ensureCapacity(chunk);
-        fName[chunk][index] = fStringPool.addSymbol(name);
-        fValue[chunk][index] = fStringPool.addString(value);
-        fPublicId[chunk][index] = -1;
-        fSystemId[chunk][index] = -1;
-        fBaseSystemId[chunk][index] = -1;
-        fNotationName[chunk][index] = -1;
-        fEntityCount++;
-    }
-    //
-    //
-    //
-    private boolean ensureCapacity(int chunk) {
-        try {
-            return fName[chunk][0] == 0;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            int[][] newIntArray = new int[chunk * 2][];
-            System.arraycopy(fName, 0, newIntArray, 0, chunk);
-            fName = newIntArray;
-            newIntArray = new int[chunk * 2][];
-            System.arraycopy(fValue, 0, newIntArray, 0, chunk);
-            fValue = newIntArray;
-            newIntArray = new int[chunk * 2][];
-            System.arraycopy(fPublicId, 0, newIntArray, 0, chunk);
-            fPublicId = newIntArray;
-            newIntArray = new int[chunk * 2][];
-            System.arraycopy(fSystemId, 0, newIntArray, 0, chunk);
-            newIntArray = new int[chunk * 2][];
-            System.arraycopy(fBaseSystemId, 0, newIntArray, 0, chunk);
-            fBaseSystemId = newIntArray;
-            fSystemId = newIntArray;
-            newIntArray = new int[chunk * 2][];
-            System.arraycopy(fNotationName, 0, newIntArray, 0, chunk);
-            fNotationName = newIntArray;
-            byte[][] newByteArray = new byte[chunk * 2][];
-            System.arraycopy(fDeclIsExternal, 0, newByteArray, 0, chunk);
-            fDeclIsExternal = newByteArray;
-        } catch (NullPointerException ex) {
-        }
-        fName[chunk] = new int[CHUNK_SIZE];
-        fValue[chunk] = new int[CHUNK_SIZE];
-        fPublicId[chunk] = new int[CHUNK_SIZE];
-        fSystemId[chunk] = new int[CHUNK_SIZE];
-        fBaseSystemId[chunk] = new int[CHUNK_SIZE];
-        fNotationName[chunk] = new int[CHUNK_SIZE];
-        fDeclIsExternal[chunk] = new byte[CHUNK_SIZE];
-        return true;
-    }
-    public int addEntityDecl(int name, int value, int publicId, int systemId, int baseSystemId, int notationName, boolean isExternal) {
-        int chunk = fEntityCount >> CHUNK_SHIFT;
-        int index = fEntityCount & CHUNK_MASK;
-        ensureCapacity(chunk);
-        fName[chunk][index] = name;
-        fValue[chunk][index] = value;
-        fPublicId[chunk][index] = publicId;
-        fSystemId[chunk][index] = systemId;
-        fBaseSystemId[chunk][index] = baseSystemId;
-        fNotationName[chunk][index] = notationName;
-        fDeclIsExternal[chunk][index] = isExternal ? (byte)0x80 : (byte)0;
-        int entityIndex = fEntityCount++;
-        return entityIndex;
-    }
-    public int addNotationDecl(int notationName, int publicId, int systemId, int baseSystemId, boolean isExternal) {
-        int nIndex = fNotationListHead;
-        while (nIndex != -1) {
-            int chunk = nIndex >> CHUNK_SHIFT;
-            int index = nIndex & CHUNK_MASK;
-            if (fNotationName[chunk][index] == notationName)
-                return -1;
-            nIndex = fValue[chunk][index];
-        }
-        int chunk = fEntityCount >> CHUNK_SHIFT;
-        int index = fEntityCount & CHUNK_MASK;
-        ensureCapacity(chunk);
-        fName[chunk][index] = -1;
-        fValue[chunk][index] = fNotationListHead;
-        fPublicId[chunk][index] = publicId;
-        fSystemId[chunk][index] = systemId;
-        fBaseSystemId[chunk][index] = baseSystemId;
-        fNotationName[chunk][index] = notationName;
-        fDeclIsExternal[chunk][index] = isExternal ? (byte)0x80 : (byte)0;
-        fNotationListHead = fEntityCount++;
-        return fNotationListHead;
-    }
-    public int lookupEntity(int nameIndex) {
-        if (nameIndex == -1)
-            return -1;
-        int chunk = 0;
-        int index = 0;
-        for (int entityIndex = 0; entityIndex < fEntityCount; entityIndex++) {
-            if (fName[chunk][index] == nameIndex)
-                return entityIndex;
-            if (++index == CHUNK_SIZE) {
-                chunk++;
-                index = 0;
-            }
-        }
-        return -1;
-    }
-    public boolean isExternalEntity(int entityIndex) {
-        int chunk = entityIndex >> CHUNK_SHIFT;
-        int index = entityIndex & CHUNK_MASK;
-        return (fValue[chunk][index] == -1);
-    }
-    public boolean isUnparsedEntity(int entityIndex) {
-        int chunk = entityIndex >> CHUNK_SHIFT;
-        int index = entityIndex & CHUNK_MASK;
-        return (fNotationName[chunk][index] != -1);
-    }
-    public boolean getEntityDeclIsExternal(int entityIndex) {
-        int chunk = entityIndex >> CHUNK_SHIFT;
-        int index = entityIndex & CHUNK_MASK;
-        return (fDeclIsExternal[chunk][index] < 0);
-    }
-    public int getEntityName(int entityIndex) {
-        int chunk = entityIndex >> CHUNK_SHIFT;
-        int index = entityIndex & CHUNK_MASK;
-        return fName[chunk][index];
-    }
-    public int getEntityValue(int entityIndex) {
-        int chunk = entityIndex >> CHUNK_SHIFT;
-        int index = entityIndex & CHUNK_MASK;
-        return fValue[chunk][index];
-    }
-    public int getPublicId(int entityIndex) {
-        int chunk = entityIndex >> CHUNK_SHIFT;
-        int index = entityIndex & CHUNK_MASK;
-        return fPublicId[chunk][index];
-    }
-    public int getSystemId(int entityIndex) {
-        int chunk = entityIndex >> CHUNK_SHIFT;
-        int index = entityIndex & CHUNK_MASK;
-        return fSystemId[chunk][index];
-    }
-    public String getBaseSystemId(int entityIndex) {
-        int chunk = entityIndex >> CHUNK_SHIFT;
-        int index = entityIndex & CHUNK_MASK;
-        int baseIndex = fBaseSystemId[chunk][index];
-        if (baseIndex == -1) {
-            return null;
-        } else {
-            return fStringPool.toString(baseIndex);
-        }
-    }
-    public boolean isNotationDeclared(int nameIndex) {
-        int nIndex = fNotationListHead;
-        while (nIndex != -1) {
-            int chunk = nIndex >> CHUNK_SHIFT;
-            int index = nIndex & CHUNK_MASK;
-            if (fNotationName[chunk][index] == nameIndex)
-                return true;
-            nIndex = fValue[chunk][index];
-        }
-        return false;
-    }
-    public boolean getNotationDeclIsExternal(int entityIndex) {
-        int chunk = entityIndex >> CHUNK_SHIFT;
-        int index = entityIndex & CHUNK_MASK;
-        return (fDeclIsExternal[chunk][index] < 0);
-    }
-    public int getNotationName(int entityIndex) {
-        int chunk = entityIndex >> CHUNK_SHIFT;
-        int index = entityIndex & CHUNK_MASK;
-        return fNotationName[chunk][index];
-    }
-    class RequiredNotation {
-        RequiredNotation(int notationName, Locator locator, int majorCode, int minorCode, Object[] args) {
-            fNotationName = notationName;
-            fLocator = new LocatorImpl(locator); // snapshot of the current location
-            fMajorCode = majorCode;
-            fMinorCode = minorCode;
-            fArgs = args;
-        }
-        int fNotationName;
-        LocatorImpl fLocator;
-        int fMajorCode;
-        int fMinorCode;
-        Object[] fArgs;
-    };
-    public void addRequiredNotation(int notationName, Locator locator, int majorCode, int minorCode, Object[] args) {
-        if (fRequiredNotations == null)
-            fRequiredNotations = new Vector();
-        for (int index = 0; index < fRequiredNotations.size(); index++) {
-            RequiredNotation rn = (RequiredNotation)fRequiredNotations.elementAt(index);
-            if (rn.fNotationName == notationName)
-                return; // REVISIT - do we want to keep just the first, or all of them?
-        }
-        fRequiredNotations.addElement(new RequiredNotation(notationName, locator, majorCode, minorCode, args));
-    }
-    public void checkRequiredNotations() throws Exception {
-        if (fRequiredNotations == null)
-            return;
-        for (int index = 0; index < fRequiredNotations.size(); index++) {
-            RequiredNotation rn = (RequiredNotation)fRequiredNotations.elementAt(index);
-            if (!isNotationDeclared(rn.fNotationName)) {
-                fErrorReporter.reportError(rn.fLocator,
-                                           XMLMessages.XML_DOMAIN,
-                                           rn.fMajorCode,
-                                           rn.fMinorCode,
-                                           rn.fArgs,
-                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-            }
-        }
-    }
-}
-}
diff --git a/src/org/apache/xerces/readers/DefaultReaderFactory.java b/src/org/apache/xerces/readers/DefaultReaderFactory.java
deleted file mode 100644
index 9af2b8d..0000000
--- a/src/org/apache/xerces/readers/DefaultReaderFactory.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.ChunkyByteArray;
-import org.apache.xerces.utils.StringPool;
-import org.xml.sax.InputSource;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.URL;
-import java.util.Stack;
-
-public class DefaultReaderFactory implements XMLEntityReaderFactory {
-    //
-    // Constants
-    //
-    private static final boolean USE_CHAR_READER_FOR_UTF8 = false;
-    private static final boolean USE_BYTE_READER_FOR_UTF8 = true;
-
-    //
-    // Instance variables
-    //
-    private boolean fSendCharDataAsCharArray = false;
-    private boolean fAllowJavaEncodingName = false;
-    private Stack fRecognizers = null;
-
-    /**
-        * Constructor
-        */
-    public DefaultReaderFactory() {
-    }
-
-    /**
-        * Adds a recognizer.
-        *
-        * @param recognizer The XML recognizer to add.
-        */
-    public void addRecognizer(XMLDeclRecognizer recognizer) {
-        if (fRecognizers == null) {
-            fRecognizers = new Stack();
-            XMLDeclRecognizer.registerDefaultRecognizers(fRecognizers);
-        }
-        fRecognizers.push(recognizer);
-    }
-
-    /**
-        * Set char data processing preference.
-        */
-    public void setSendCharDataAsCharArray(boolean flag) {
-        fSendCharDataAsCharArray = flag;
-    }
-
-    /**
-        *
-        */
-    public void setAllowJavaEncodingName(boolean flag) {
-        fAllowJavaEncodingName = flag;
-    }
-
-    /**
-        *
-        */
-    public boolean getAllowJavaEncodingName() {
-        return fAllowJavaEncodingName;
-    }
-
-    /**
-        * Create a reader
-        */
-    public XMLEntityHandler.EntityReader createReader(XMLEntityHandler entityHandler,
-                                                            XMLErrorReporter errorReporter,
-                                                            InputSource source,
-                                                      String systemId, boolean xmlDecl, StringPool stringPool) throws Exception {
-
-        // create reader from source's character stream
-        if (source.getCharacterStream() != null) {
-            return createCharReader(entityHandler, errorReporter, fSendCharDataAsCharArray, source.getCharacterStream(), stringPool);
-        }
-
-        // create reader from source's byte stream
-        if (source.getEncoding() != null && source.getByteStream() != null) {
-            java.io.Reader reader = new InputStreamReader(source.getByteStream(), source.getEncoding());
-            return createCharReader(entityHandler, errorReporter, fSendCharDataAsCharArray, reader, stringPool);
-        }
-
-        // create new input stream
-        InputStream is = source.getByteStream();
-        if (is == null) {
-
-            // create url and open the stream
-            URL url = new URL(systemId);
-            is = url.openStream();
-        }
-
-        // create array and find recognizer
-        ChunkyByteArray data = new ChunkyByteArray(is);
-        if (fRecognizers == null) {
-            fRecognizers = new Stack();
-            XMLDeclRecognizer.registerDefaultRecognizers(fRecognizers);
-        }
-        for (int i = fRecognizers.size() - 1; i >= 0; i--) {
-            XMLDeclRecognizer recognizer = (XMLDeclRecognizer)fRecognizers.elementAt(i);
-            XMLEntityHandler.EntityReader reader = recognizer.recognize(this, entityHandler, errorReporter, fSendCharDataAsCharArray, stringPool, data, xmlDecl, fAllowJavaEncodingName);
-            if (reader != null) {
-                return reader;
-            }
-        }
-        return createUTF8Reader(entityHandler, errorReporter, fSendCharDataAsCharArray, data, stringPool);
-    }
-
-    /**
-        * Create an entity reader for a character stream.
-        *
-        * @param enityHandler The entity handler.
-        * @param errorReporter The error reporter.
-        * @param sendCharDataAsCharArray true if char data should be reported using
-        *                                char arrays instead of string handles.
-        * @param reader The character stream.
-        * @param stringPool The string pool.
-        * @return The reader that will process the character data.
-        * @exception java.lang.Exception
-        */
-    public XMLEntityHandler.EntityReader createCharReader(XMLEntityHandler entityHandler,
-                                                            XMLErrorReporter errorReporter,
-                                                            boolean sendCharDataAsCharArray,
-                                                            Reader reader,
-                                                            StringPool stringPool) throws Exception
-    {
-        return new CharReader(entityHandler, errorReporter, sendCharDataAsCharArray, reader, stringPool);
-    }
-
-    /**
-        * Create an entity reader for a byte stream encoded in UTF-8.
-        *
-        * @param enityHandler The entity handler.
-        * @param errorReporter The error reporter.
-        * @param sendCharDataAsCharArray true if char data should be reported using
-        *                                char arrays instead of string handles.
-        * @param data The byte stream.
-        * @param stringPool The string pool.
-        * @return The reader that will process the UTF-8 data.
-        * @exception java.lang.Exception
-        */
-    public XMLEntityHandler.EntityReader createUTF8Reader(XMLEntityHandler entityHandler,
-                                                            XMLErrorReporter errorReporter,
-                                                            boolean sendCharDataAsCharArray,
-                                                            InputStream data,
-                                                            StringPool stringPool) throws Exception
-    {
-        XMLEntityHandler.EntityReader reader;
-        if (USE_CHAR_READER_FOR_UTF8) {
-            reader = new CharReader(entityHandler, errorReporter, sendCharDataAsCharArray, new InputStreamReader(data, "UTF8"), stringPool);
-        } else if (USE_BYTE_READER_FOR_UTF8) {
-            reader = new UTF8Reader(entityHandler, errorReporter, sendCharDataAsCharArray, data, stringPool);
-        } else {
-            reader = new UTF8CharReader(entityHandler, errorReporter, sendCharDataAsCharArray, data, stringPool);
-        }
-        return reader;
-    }
-
-    /**
-        * Create an entity reader for data from a String.
-        *
-        * @param entityHandler The current entity handler.
-        * @param errorReporter The current error reporter.
-        * @param sendCharDataAsCharArray true if char data should be reported using
-        *                                char arrays instead of string handles.
-        * @param lineNumber The line number to return as our position.
-        * @param columnNumber The column number to return as our position.
-        * @param stringHandle The StringPool handle for the data to process.
-        * @param stringPool The string pool.
-        * @param addEnclosingSpaces If true, treat the data to process as if
-        *                           there were a leading and trailing space
-        *                           character enclosing the string data.
-        * @return The reader that will process the string data.
-        * @exception java.lang.Exception
-        */
-    public XMLEntityHandler.EntityReader createStringReader(XMLEntityHandler entityHandler,
-                                                            XMLErrorReporter errorReporter,
-                                                            boolean sendCharDataAsCharArray,
-                                                            int lineNumber,
-                                                            int columnNumber,
-                                                            int stringHandle,
-                                                            StringPool stringPool,
-                                                            boolean addEnclosingSpaces) throws Exception
-    {
-        return StringReader.createStringReader(entityHandler, errorReporter, sendCharDataAsCharArray,
-                                                lineNumber, columnNumber, stringHandle, stringPool, addEnclosingSpaces);
-    }
-}
diff --git a/src/org/apache/xerces/readers/EBCDICRecognizer.java b/src/org/apache/xerces/readers/EBCDICRecognizer.java
deleted file mode 100644
index 33b4789..0000000
--- a/src/org/apache/xerces/readers/EBCDICRecognizer.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.ChunkyByteArray;
-import org.apache.xerces.utils.StringPool;
-
-import java.io.InputStreamReader;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-
-/**
- *
- * @version
- */
-final class EBCDICRecognizer extends XMLDeclRecognizer {
-    //
-    //
-    //
-    public XMLEntityHandler.EntityReader recognize(XMLEntityReaderFactory readerFactory,
-                                                   XMLEntityHandler entityHandler,
-                                                   XMLErrorReporter errorReporter,
-                                                   boolean sendCharDataAsCharArray,
-                                                   StringPool stringPool,
-                                                   ChunkyByteArray data,
-                                                   boolean xmlDecl,
-                                                   boolean allowJavaEncodingName) throws Exception
-    {
-        XMLEntityHandler.EntityReader reader = null;
-        byte b0 = data.byteAt(0);
-        byte b1 = data.byteAt(1);
-        byte b2 = data.byteAt(2);
-        byte b3 = data.byteAt(3);
-        boolean debug = false;
-
-        if (b0 != 0x4c || b1 != 0x6f || b2 != (byte)0xa7 || b3 != (byte)0x94)
-            return reader;
-        XMLEntityHandler.EntityReader declReader = readerFactory.createCharReader(entityHandler, errorReporter, sendCharDataAsCharArray, new InputStreamReader(data, "CP037"), stringPool);
-        int encoding = prescanXMLDeclOrTextDecl(declReader, xmlDecl);
-        if (encoding == -1) {
-            data.rewind();
-            // REVISIT - The document is not well-formed.  There is no encoding, yet the file is
-            //   clearly not UTF8.
-            throw new UnsupportedEncodingException(null);
-        }
-        String enc = stringPool.orphanString(encoding).toUpperCase();
-        if ("ISO-10646-UCS-2".equals(enc)) throw new UnsupportedEncodingException(enc);
-        if ("ISO-10646-UCS-4".equals(enc)) throw new UnsupportedEncodingException(enc);
-        if ("UTF-16".equals(enc)) throw new UnsupportedEncodingException(enc);
-        String javaencname = MIME2Java.convert(enc);
-        if (null == javaencname) {
-            if (allowJavaEncodingName) {
-                javaencname = enc;
-            } else {
-                throw new UnsupportedEncodingException(enc);
-            }
-        }
-        try {
-            data.rewind();
-            reader = readerFactory.createCharReader(entityHandler, errorReporter, sendCharDataAsCharArray, new InputStreamReader(data, javaencname), stringPool);
-        } catch (UnsupportedEncodingException e) {
-            throw e;
-        } catch (Exception e) {
-            if( debug == true )
-                e.printStackTrace();            // Internal Error
-        }
-        return reader;
-    }
-}
diff --git a/src/org/apache/xerces/readers/MIME2Java.java b/src/org/apache/xerces/readers/MIME2Java.java
deleted file mode 100644
index 4d8d70c..0000000
--- a/src/org/apache/xerces/readers/MIME2Java.java
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import java.util.*;
-
-/**
- * MIME2Java is a convenience class which handles conversions between MIME charset names
- * and Java encoding names.
- * <p>The supported XML encodings are the intersection of XML-supported code sets and those 
- * supported in JDK 1.1.
- * <p>MIME charset names are used on <var>xmlEncoding</var> parameters to methods such
- * as <code>TXDocument#setEncoding</code> and <code>DTD#setEncoding</code>.
- * <p>Java encoding names are used on <var>encoding</var> parameters to
- * methods such as <code>TXDocument#printWithFormat</code> and <code>DTD#printExternal</code>. 
- * <P>
- * <TABLE BORDER="0" WIDTH="100%">
- *  <TR>
- *      <TD WIDTH="33%">
- *          <P ALIGN="CENTER"><B>Common Name</B>
- *      </TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER"><B>Use this name in XML files</B>
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER"><B>Name Type</B>
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER"><B>Xerces converts to this Java Encoder Name</B>
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">8 bit Unicode</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">UTF-8
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">UTF8
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">ISO Latin 1</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ISO-8859-1
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">ISO-8859-1
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">ISO Latin 2</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ISO-8859-2
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">ISO-8859-2
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">ISO Latin 3</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ISO-8859-3
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">ISO-8859-3
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">ISO Latin 4</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ISO-8859-4
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">ISO-8859-4
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">ISO Latin Cyrillic</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ISO-8859-5
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">ISO-8859-5
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">ISO Latin Arabic</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ISO-8859-6
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">ISO-8859-6
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">ISO Latin Greek</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ISO-8859-7
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">ISO-8859-7
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">ISO Latin Hebrew</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ISO-8859-8
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">ISO-8859-8
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">ISO Latin 5</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ISO-8859-9
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">ISO-8859-9
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: US</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-us
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp037
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Canada</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-ca
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp037
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Netherlands</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-nl
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp037
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Denmark</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-dk
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp277
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Norway</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-no
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp277
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Finland</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-fi
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp278
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Sweden</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-se
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp278
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Italy</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-it
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp280
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Spain, Latin America</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-es
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp284
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Great Britain</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-gb
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp285
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: France</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-fr
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp297
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Arabic</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-ar1
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp420
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Hebrew</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-he
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp424
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Switzerland</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-ch
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp500
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Roece</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-roece
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp870
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Yogoslavia</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-yu
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp870
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Iceland</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-is
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp871
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">EBCDIC: Urdu</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">ebcdic-cp-ar2
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">IANA
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">cp918
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">Chinese for PRC, mixed 1/2 byte</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">gb2312
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">GB2312
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">Extended Unix Code, packed for Japanese</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">euc-jp
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">eucjis
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">Japanese: iso-2022-jp</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">iso-2020-jp
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">JIS
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">Japanese: Shift JIS</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">Shift_JIS
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">SJIS
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">Chinese: Big5</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">Big5
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">Big5
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">Extended Unix Code, packed for Korean</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">euc-kr
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">iso2022kr
- *      </TD>
- *  </TR>
- *  <TR>
- *      <TD WIDTH="33%">Cyrillic</TD>
- *      <TD WIDTH="15%">
- *          <P ALIGN="CENTER">koi8-r
- *      </TD>
- *      <TD WIDTH="12%">
- *          <P ALIGN="CENTER">MIME
- *      </TD>
- *      <TD WIDTH="31%">
- *          <P ALIGN="CENTER">koi8-r
- *      </TD>
- *  </TR>
- * </TABLE>
- * 
- * @version
- * @author TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;
- */
-public class MIME2Java {
-    
-    static private Hashtable s_enchash;
-    static private Hashtable s_revhash;
-    
-    static {
-        s_enchash = new Hashtable();
-        //    <preferred MIME name>, <Java encoding name>
-        s_enchash.put("UTF-8", "UTF8");
-        s_enchash.put("US-ASCII",        "8859_1");    // ?
-        s_enchash.put("ISO-8859-1",      "8859_1");
-        s_enchash.put("ISO-8859-2",      "8859_2");
-        s_enchash.put("ISO-8859-3",      "8859_3");
-        s_enchash.put("ISO-8859-4",      "8859_4");
-        s_enchash.put("ISO-8859-5",      "8859_5");
-        s_enchash.put("ISO-8859-6",      "8859_6");
-        s_enchash.put("ISO-8859-7",      "8859_7");
-        s_enchash.put("ISO-8859-8",      "8859_8");
-        s_enchash.put("ISO-8859-9",      "8859_9");
-        s_enchash.put("ISO-2022-JP",     "JIS");
-        s_enchash.put("SHIFT_JIS",       "SJIS");
-        s_enchash.put("EUC-JP",          "EUCJIS");
-        s_enchash.put("GB2312",          "GB2312");
-        s_enchash.put("BIG5",            "Big5");
-        s_enchash.put("EUC-KR",          "KSC5601");
-        s_enchash.put("ISO-2022-KR",     "ISO2022KR");
-        s_enchash.put("KOI8-R",          "KOI8_R");
-
-        s_enchash.put("EBCDIC-CP-US",    "CP037");
-        s_enchash.put("EBCDIC-CP-CA",    "CP037");
-        s_enchash.put("EBCDIC-CP-NL",    "CP037");
-        s_enchash.put("EBCDIC-CP-DK",    "CP277");
-        s_enchash.put("EBCDIC-CP-NO",    "CP277");
-        s_enchash.put("EBCDIC-CP-FI",    "CP278");
-        s_enchash.put("EBCDIC-CP-SE",    "CP278");
-        s_enchash.put("EBCDIC-CP-IT",    "CP280");
-        s_enchash.put("EBCDIC-CP-ES",    "CP284");
-        s_enchash.put("EBCDIC-CP-GB",    "CP285");
-        s_enchash.put("EBCDIC-CP-FR",    "CP297");
-        s_enchash.put("EBCDIC-CP-AR1",   "CP420");
-        s_enchash.put("EBCDIC-CP-HE",    "CP424");
-        s_enchash.put("EBCDIC-CP-CH",    "CP500");
-        s_enchash.put("EBCDIC-CP-ROECE", "CP870");
-        s_enchash.put("EBCDIC-CP-YU",    "CP870");
-        s_enchash.put("EBCDIC-CP-IS",    "CP871");
-        s_enchash.put("EBCDIC-CP-AR2",   "CP918");
-
-                                                // j:CNS11643 -> EUC-TW?
-                                                // ISO-2022-CN? ISO-2022-CN-EXT?
-                                                
-        s_revhash = new Hashtable();
-        //    <Java encoding name>, <preferred MIME name>
-        s_revhash.put("UTF8", "UTF-8");
-        //s_revhash.put("8859_1", "US-ASCII");    // ?
-        s_revhash.put("8859_1", "ISO-8859-1");
-        s_revhash.put("8859_2", "ISO-8859-2");
-        s_revhash.put("8859_3", "ISO-8859-3");
-        s_revhash.put("8859_4", "ISO-8859-4");
-        s_revhash.put("8859_5", "ISO-8859-5");
-        s_revhash.put("8859_6", "ISO-8859-6");
-        s_revhash.put("8859_7", "ISO-8859-7");
-        s_revhash.put("8859_8", "ISO-8859-8");
-        s_revhash.put("8859_9", "ISO-8859-9");
-        s_revhash.put("JIS", "ISO-2022-JP");
-        s_revhash.put("SJIS", "Shift_JIS");
-        s_revhash.put("EUCJIS", "EUC-JP");
-        s_revhash.put("GB2312", "GB2312");
-        s_revhash.put("BIG5", "Big5");
-        s_revhash.put("KSC5601", "EUC-KR");
-        s_revhash.put("ISO2022KR", "ISO-2022-KR");
-        s_revhash.put("KOI8_R", "KOI8-R");
-
-        s_revhash.put("CP037", "EBCDIC-CP-US");
-        s_revhash.put("CP037", "EBCDIC-CP-CA");
-        s_revhash.put("CP037", "EBCDIC-CP-NL");
-        s_revhash.put("CP277", "EBCDIC-CP-DK");
-        s_revhash.put("CP277", "EBCDIC-CP-NO");
-        s_revhash.put("CP278", "EBCDIC-CP-FI");
-        s_revhash.put("CP278", "EBCDIC-CP-SE");
-        s_revhash.put("CP280", "EBCDIC-CP-IT");
-        s_revhash.put("CP284", "EBCDIC-CP-ES");
-        s_revhash.put("CP285", "EBCDIC-CP-GB");
-        s_revhash.put("CP297", "EBCDIC-CP-FR");
-        s_revhash.put("CP420", "EBCDIC-CP-AR1");
-        s_revhash.put("CP424", "EBCDIC-CP-HE");
-        s_revhash.put("CP500", "EBCDIC-CP-CH");
-        s_revhash.put("CP870", "EBCDIC-CP-ROECE");
-        s_revhash.put("CP870", "EBCDIC-CP-YU");
-        s_revhash.put("CP871", "EBCDIC-CP-IS");
-        s_revhash.put("CP918", "EBCDIC-CP-AR2");
-    }
-
-    private MIME2Java() {
-    }
-
-    /**
-     * Convert a MIME charset name, also known as an XML encoding name, to a Java encoding name.
-     * @param   mimeCharsetName Case insensitive MIME charset name: <code>UTF-8, US-ASCII, ISO-8859-1,
-     *                          ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6,
-     *                          ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-2022-JP, Shift_JIS, 
-     *                          EUC-JP, GB2312, Big5, EUC-KR, ISO-2022-KR, KOI8-R,
-     *                          EBCDIC-CP-US, EBCDIC-CP-CA, EBCDIC-CP-NL, EBCDIC-CP-DK,
-     *                          EBCDIC-CP-NO, EBCDIC-CP-FI, EBCDIC-CP-SE, EBCDIC-CP-IT,
-     *                          EBCDIC-CP-ES, EBCDIC-CP-GB, EBCDIC-CP-FR, EBCDIC-CP-AR1,
-     *                          EBCDIC-CP-HE, EBCDIC-CP-CH, EBCDIC-CP-ROECE, EBCDIC-CP-YU,
-     *                          EBCDIC-CP-IS and EBCDIC-CP-AR2</code>.
-     * @return                  Java encoding name, or <var>null</var> if <var>mimeCharsetName</var>
-     *                          is unknown.
-     * @see #reverse
-     */
-    public static String convert(String mimeCharsetName) {
-        return (String)s_enchash.get(mimeCharsetName.toUpperCase());
-    }
-
-    /**
-     * Convert a Java encoding name to MIME charset name.
-     * Available values of <i>encoding</i> are "UTF8", "8859_1", "8859_2", "8859_3", "8859_4",
-     * "8859_5", "8859_6", "8859_7", "8859_8", "8859_9", "JIS", "SJIS", "EUCJIS",
-     * "GB2312", "BIG5", "KSC5601", "ISO2022KR",  "KOI8_R", "CP037", "CP277", "CP278",
-     * "CP280", "CP284", "CP285", "CP297", "CP420", "CP424", "CP500", "CP870", "CP871" and "CP918".
-     * @param   encoding    Case insensitive Java encoding name: <code>UTF8, 8859_1, 8859_2, 8859_3,
-     *                      8859_4, 8859_5, 8859_6, 8859_7, 8859_8, 8859_9, JIS, SJIS, EUCJIS,
-     *                      GB2312, BIG5, KSC5601, ISO2022KR, KOI8_R, CP037, CP277, CP278,
-     *                      CP280, CP284, CP285, CP297, CP420, CP424, CP500, CP870, CP871 
-     *                      and CP918</code>.
-     * @return              MIME charset name, or <var>null</var> if <var>encoding</var> is unknown.
-     * @see #convert
-     */
-    public static String reverse(String encoding) {
-        return (String)s_revhash.get(encoding.toUpperCase());
-    }
-}
diff --git a/src/org/apache/xerces/readers/Makefile b/src/org/apache/xerces/readers/Makefile
deleted file mode 100644
index d66810b..0000000
--- a/src/org/apache/xerces/readers/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-# Makefile for directory ./org/apache/xerces/readers
-
-TARGETS=\
-	AbstractCharReader.class\
-	CharReader.class\
-	DefaultEntityHandler.class\
-	DefaultReaderFactory.class\
-	EBCDICRecognizer.class\
-	MIME2Java.class\
-	StreamingCharReader.class\
-	StringReader.class\
-	UCSReader.class\
-	UCSRecognizer.class\
-	UTF8CharReader.class\
-	UTF8Reader.class\
-	UTF8Recognizer.class\
-	XCatalog.class\
-	XMLCatalogHandler.class\
-	XMLDeclRecognizer.class\
-	XMLEntityHandler.class\
-	XMLEntityReader.class\
-	XMLEntityReaderFactory.class
-
-DIRS = 
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xerces/readers/StreamingCharReader.java b/src/org/apache/xerces/readers/StreamingCharReader.java
deleted file mode 100644
index 716c2ba..0000000
--- a/src/org/apache/xerces/readers/StreamingCharReader.java
+++ /dev/null
@@ -1,1388 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.CharDataChunk;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringHasher;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.utils.XMLCharacterProperties;
-import org.apache.xerces.utils.ImplementationMessages;
-import org.xml.sax.SAXParseException;
-import java.io.Reader;
-import java.util.Vector;
-
-/**
- * An reader class for applications that need to process input data as 
- * it arrives on the stream.
- * 
- * @version $Id$
- */
-public class StreamingCharReader extends XMLEntityReader {
-
-    /**
-     * Constructor
-     *
-     * @param entityHandler The entity handler.
-     * @param errorReporter The error reporter.
-     * @param sendCharDataAsCharArray true if char data should be reported using
-     *                                char arrays instead of string handles.
-     * @param stringPool The string pool.
-     */
-    public StreamingCharReader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter, boolean sendCharDataAsCharArray, Reader reader, StringPool stringPool) throws Exception {
-        super(entityHandler, errorReporter, sendCharDataAsCharArray);
-        fStringPool = stringPool;
-        fCharacterStream = reader;
-        fCurrentChunk = CharDataChunk.createChunk(fStringPool, null);
-        loadFirstChar();
-    }
-
-    /**
-     * Delay reporting an error message.
-     *
-     * If there is an error detected in the underlying input stream during
-     * the fillCurrentChunk method, the error is described here and will be
-     * reported when we reach that offset during normal processing.  The
-     * subclass should place a character with a value of zero at that offset,
-     * which will be detected here as an invalid character.  When the invalid
-     * character is scanned, we will generate the deferred exception.
-     *
-     * @param errorCode the errorCode to report
-     * @param args an array of arguments needed to generate a good error message
-     * @param offset the position in the reader where the error occured
-     */
-    protected void deferException(int errorCode, Object[] args, int offset) {
-        if (fDeferredErrors == null)
-            fDeferredErrors = new Vector();
-        DeferredError de = new DeferredError(errorCode, args, offset);
-        fDeferredErrors.addElement(de);
-    }
-
-    /**
-     * Change readers at end of input.
-     *
-     * We override our superclass method to release the final chunk
-     * of the input data before handing off to the next reader.
-     *
-     * @return The next reader used to continue processing the document.
-     */
-    protected XMLEntityHandler.EntityReader changeReaders() throws Exception {
-        XMLEntityHandler.EntityReader nextReader = super.changeReaders();
-        fCurrentChunk.releaseChunk();
-        fCurrentChunk = null;
-        return nextReader;
-    }
-
-    //
-    // XMLEntityHandler.EntityReader implementation
-    //
-    // The first five methods of the interface are implemented
-    // in the XMLEntityHandler base class for us, namely
-    //
-    //    public int currentOffset();
-    //    public int getLineNumber();
-    //    public int getColumnNumber();
-    //    public void setInCDSect(boolean inCDSect);
-    //    public boolean getInCDSect();
-    //
-
-    /**
-     * Append the characters processed by this reader associated with <code>offset</code> and
-     * <code>length</code> to the <code>CharBuffer</code>.
-     *
-     * @param charBuffer The <code>CharBuffer</code> to append the characters to.
-     * @param offset The offset within this reader where the copy should start.
-     * @param length The length within this reader where the copy should stop.
-     */
-    public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length) {
-        fCurrentChunk.append(charBuffer, offset, length);
-    }
-
-    /**
-     * Add a string to the <code>StringPool</code> from the characters scanned using this
-     * reader as described by <code>offset</code> and <code>length</code>.
-     *
-     * @param offset The offset within this reader where the characters start.
-     * @param length The length within this reader where the characters end.
-     * @return The <code>StringPool</code> handle for the string.
-     */
-    public int addString(int offset, int length) {
-        if (length == 0)
-            return 0;
-        return fCurrentChunk.addString(offset, length);
-    }
-
-    /**
-     * Add a symbol to the <code>StringPool</code> from the characters scanned using this
-     * reader as described by <code>offset</code> and <code>length</code>.
-     *
-     * @param offset The offset within this reader where the characters start.
-     * @param length The length within this reader where the characters end.
-     * @return The <code>StringPool</code> handle for the symbol.
-     */
-    public int addSymbol(int offset, int length) {
-        if (length == 0)
-            return 0;
-        return fCurrentChunk.addSymbol(offset, length, 0);
-    }
-
-    /**
-     *
-     */
-    public boolean lookingAtChar(char chr, boolean skipPastChar) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch != chr) {
-            if (ch == 0) {
-                if (atEOF(fCurrentOffset + 1)) {
-                    return changeReaders().lookingAtChar(chr, skipPastChar);
-                }
-            }
-            return false;
-        }
-        if (skipPastChar) {
-            fCharacterCounter++;
-            loadNextChar();
-        }
-        return true;
-    }
-
-    /**
-     *
-     */
-    public boolean lookingAtValidChar(boolean skipPastChar) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch < 0xD800) {
-            if (ch >= 0x20 || ch == 0x09) {
-                if (skipPastChar) {
-                    fCharacterCounter++;
-                    loadNextChar();
-                }
-                return true;
-            }
-            if (ch == 0x0A) {
-                if (skipPastChar) {
-                    fLinefeedCounter++;
-                    fCharacterCounter = 1;
-                    loadNextChar();
-                }
-                return true;
-            }
-            if (ch == 0) {
-                if (atEOF(fCurrentOffset + 1)) {
-                    return changeReaders().lookingAtValidChar(skipPastChar);
-                }
-            }
-            return false;
-        }
-        if (ch > 0xFFFD) {
-            return false;
-        }
-        if (ch < 0xDC00) {
-            CharDataChunk savedChunk = fCurrentChunk;
-            int savedIndex = fCurrentIndex;
-            int savedOffset = fCurrentOffset;
-            ch = loadNextChar();
-            boolean valid = (ch >= 0xDC00 && ch < 0xE000);
-            if (!valid || !skipPastChar) {
-                fCurrentChunk = savedChunk;
-                fCurrentIndex = savedIndex;
-                fCurrentOffset = savedOffset;
-                fMostRecentData = savedChunk.toCharArray();
-                fMostRecentChar = fMostRecentData[savedIndex] & 0xFFFF;
-                return valid;
-            }
-        } else if (ch < 0xE000) {
-            return false;
-        }
-        if (skipPastChar) {
-            fCharacterCounter++;
-            loadNextChar();
-        }
-        return true;
-    }
-
-    /**
-     *
-     */
-    public boolean lookingAtSpace(boolean skipPastChar) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch > 0x20)
-            return false;
-        if (ch == 0x20 || ch == 0x09) {
-            if (!skipPastChar)
-                return true;
-            fCharacterCounter++;
-        } else if (ch == 0x0A) {
-            if (!skipPastChar)
-                return true;
-            fLinefeedCounter++;
-            fCharacterCounter = 1;
-        } else {
-            if (ch == 0) { // REVISIT - should we be checking this here ?
-                if (atEOF(fCurrentOffset + 1)) {
-                    return changeReaders().lookingAtSpace(skipPastChar);
-                }
-            }
-            return false;
-        }
-        loadNextChar();
-        return true;
-    }
-
-    /**
-     *
-     */
-    public void skipToChar(char chr) throws Exception {
-        //
-        // REVISIT - this will skip invalid characters without reporting them.
-        //
-        int ch = fMostRecentChar;
-        while (true) {
-            if (ch == chr)
-                return;
-            if (ch == 0) {
-                if (atEOF(fCurrentOffset + 1)) {
-                    changeReaders().skipToChar(chr);
-                    return;
-                }
-                fCharacterCounter++;
-            } else if (ch == 0x0A) {
-                fLinefeedCounter++;
-                fCharacterCounter = 1;
-            } else if (ch >= 0xD800 && ch < 0xDC00) {
-                fCharacterCounter++;
-                ch = loadNextChar();
-                if (ch < 0xDC00 || ch >= 0xE000)
-                    continue;
-            } else
-                fCharacterCounter++;
-            ch = loadNextChar();
-        }
-    }
-
-    /**
-     *
-     */
-    public void skipPastSpaces() throws Exception {
-        int ch = fMostRecentChar;
-        while (true) {
-            if (ch == 0x20 || ch == 0x09) {
-                fCharacterCounter++;
-            } else if (ch == 0x0A) {
-                fLinefeedCounter++;
-                fCharacterCounter = 1;
-            } else {
-                if (ch == 0 && atEOF(fCurrentOffset + 1))
-                    changeReaders().skipPastSpaces();
-                return;
-            }
-            ch = loadNextChar();
-        }
-    }
-
-    /**
-     *
-     */
-    public void skipPastName(char fastcheck) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch < 0x80) {
-            if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0)
-                return;
-        } else {
-            if (!fCalledCharPropInit) {
-                XMLCharacterProperties.initCharFlags();
-                fCalledCharPropInit = true;
-            }
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
-                return;
-        }
-        while (true) {
-            fCharacterCounter++;
-            ch = loadNextChar();
-            if (fastcheck == ch)
-                return;
-            if (ch < 0x80) {
-                if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                    return;
-            } else {
-                if (!fCalledCharPropInit) {
-                    XMLCharacterProperties.initCharFlags();
-                    fCalledCharPropInit = true;
-                }
-                if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                    return;
-            }
-        }
-    }
-
-    /**
-     *
-     */
-    public void skipPastNmtoken(char fastcheck) throws Exception {
-        int ch = fMostRecentChar;
-        while (true) {
-            if (fastcheck == ch)
-                return;
-            if (ch < 0x80) {
-                if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                    return;
-            } else {
-                if (!fCalledCharPropInit) {
-                    XMLCharacterProperties.initCharFlags();
-                    fCalledCharPropInit = true;
-                }
-                if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                    return;
-            }
-            fCharacterCounter++;
-            ch = loadNextChar();
-        }
-    }
-
-    /**
-     *
-     */
-    public boolean skippedString(char[] s) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch != s[0])
-            return false;
-        int length = s.length;
-        CharDataChunk dataChunk = fCurrentChunk;
-        int offset = fCurrentOffset;
-        int index = fCurrentIndex;
-        ch = loadNextChar();
-        for (int i = 1; i < length; i++) {
-            if (ch != s[i]) {
-                fCurrentChunk = dataChunk;
-                fCurrentIndex = index;
-                fCurrentOffset = offset;
-                fMostRecentData = dataChunk.toCharArray();
-                fMostRecentChar = fMostRecentData[index] & 0xFFFF;
-                return false;
-            }
-            ch = loadNextChar();
-        }
-        fCharacterCounter += length;
-        return true;
-    }
-
-    /**
-     *
-     */
-    public int scanInvalidChar() throws Exception {
-        int ch = fMostRecentChar;
-        if (ch == 0x0A) {
-            fLinefeedCounter++;
-            fCharacterCounter = 1;
-            loadNextChar();
-        } else if (ch == 0) {
-            if (atEOF(fCurrentOffset + 1)) {
-                return changeReaders().scanInvalidChar();
-            }
-            if (fDeferredErrors != null) {
-                for (int i = 0; i < fDeferredErrors.size(); i++) {
-                    DeferredError de = (DeferredError)fDeferredErrors.elementAt(i);
-                    if (de.offset == fCurrentIndex) {
-                        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                                   ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
-                                                   de.errorCode,
-                                                   0,
-                                                   de.args,
-                                                   XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-                        fDeferredErrors.removeElementAt(i);
-                        fCharacterCounter++;
-                        loadNextChar();
-                        return -1;
-                    }
-                }
-            }
-            fCharacterCounter++;
-            loadNextChar();
-        } else {
-            fCharacterCounter++;
-            if (ch >= 0xD800 && ch < 0xDC00) {
-                int ch2 = loadNextChar();
-                if (ch2 >= 0xDC00 && ch2 < 0xE000) {
-                    ch = ((ch-0xD800)<<10)+(ch2-0xDC00)+0x10000;
-                    loadNextChar();
-                }
-            } else
-                loadNextChar();
-        }
-        return ch;
-    }
-
-    /**
-     *
-     */
-    public int scanCharRef(boolean hex) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch == 0) {
-            if (atEOF(fCurrentOffset + 1)) {
-                return changeReaders().scanCharRef(hex);
-            }
-            return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-        }
-        int num = 0;
-        if (hex) {
-            if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
-                return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-            num = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
-        } else {
-            if (ch < '0' || ch > '9')
-                return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-            num = ch - '0';
-        }
-        fCharacterCounter++;
-        loadNextChar();
-        boolean toobig = false;
-        while (true) {
-            ch = fMostRecentChar;
-            if (ch == 0)
-                break;
-            if (hex) {
-                if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
-                    break;
-            } else {
-                if (ch < '0' || ch > '9')
-                    break;
-            }
-            fCharacterCounter++;
-            loadNextChar();
-            if (hex) {
-                int dig = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
-                num = (num << 4) + dig;
-            } else {
-                int dig = ch - '0';
-                num = (num * 10) + dig;
-            }
-            if (num > 0x10FFFF) {
-                toobig = true;
-                num = 0;
-            }
-        }
-        if (ch != ';')
-            return XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED;
-        fCharacterCounter++;
-        loadNextChar();
-        if (toobig)
-            return XMLEntityHandler.CHARREF_RESULT_OUT_OF_RANGE;
-        return num;
-    }
-
-    /**
-     *
-     */
-    public int scanStringLiteral() throws Exception {
-        boolean single;
-        if (!(single = lookingAtChar('\'', true)) && !lookingAtChar('\"', true)) {
-            return XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED;
-        }
-        int offset = fCurrentOffset;
-        char qchar = single ? '\'' : '\"';
-        while (!lookingAtChar(qchar, false)) {
-            if (!lookingAtValidChar(true)) {
-                return XMLEntityHandler.STRINGLIT_RESULT_INVALID_CHAR;
-            }
-        }
-        int stringIndex = addString(offset, fCurrentOffset - offset);
-        lookingAtChar(qchar, true); // move past qchar
-        return stringIndex;
-    }
-
-    //
-    // [10] AttValue ::= '"' ([^<&"] | Reference)* '"'
-    //                   | "'" ([^<&'] | Reference)* "'"
-    //
-    /**
-     *
-     */
-    public int scanAttValue(char qchar, boolean asSymbol) throws Exception
-    {
-        int offset = fCurrentOffset;
-        while (true) {
-            if (lookingAtChar(qchar, false)) {
-                break;
-            }
-            if (lookingAtChar(' ', true)) {
-                continue;
-            }
-            if (lookingAtSpace(false)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_COMPLEX;
-            }
-            if (lookingAtChar('&', false)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_COMPLEX;
-            }
-            if (lookingAtChar('<', false)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_LESSTHAN;
-            }
-            if (!lookingAtValidChar(true)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_INVALID_CHAR;
-            }
-        }
-        int result = asSymbol ? addSymbol(offset, fCurrentOffset - offset) : addString(offset, fCurrentOffset - offset);
-        lookingAtChar(qchar, true);
-        return result;
-    }
-
-    //
-    //  [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
-    //                      | "'" ([^%&'] | PEReference | Reference)* "'"
-    //
-    /**
-     *
-     */
-    public int scanEntityValue(int qchar, boolean createString) throws Exception
-    {
-        int offset = fCurrentOffset;
-        while (true) {
-            if (atEOF(fCurrentOffset + 1)) {
-                changeReaders();
-                return XMLEntityHandler.ENTITYVALUE_RESULT_END_OF_INPUT;
-            }
-            if (qchar != -1 && lookingAtChar((char)qchar, false)) {
-                if (!createString)
-                    return XMLEntityHandler.ENTITYVALUE_RESULT_FINISHED;
-                break;
-            }
-            if (lookingAtChar('&', false)) {
-                return XMLEntityHandler.ENTITYVALUE_RESULT_REFERENCE;
-            }
-            if (lookingAtChar('%', false)) {
-                return XMLEntityHandler.ENTITYVALUE_RESULT_PEREF;
-            }
-            if (!lookingAtValidChar(true)) {
-                return XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR;
-            }
-        }
-        int result = addString(offset, fCurrentOffset - offset);
-        lookingAtChar((char)qchar, true);
-        return result;
-    }
-
-    /**
-     *
-     */
-    public int scanName(char fastcheck) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch < 0x80) {
-            if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0)
-                return -1;
-        } else {
-            if (!fCalledCharPropInit) {
-                XMLCharacterProperties.initCharFlags();
-                fCalledCharPropInit = true;
-            }
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
-                return -1;
-        }
-        int offset = fCurrentOffset;
-        fCharacterCounter++;
-        int hashcode = 0;
-        while (true) {
-            hashcode = StringHasher.hashChar(hashcode, ch);
-            ch = loadNextChar();
-            if (fastcheck == ch)
-                break;
-            if (ch < 0x80) {
-                if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                    break;
-            } else {
-                if (!fCalledCharPropInit) {
-                    XMLCharacterProperties.initCharFlags();
-                    fCalledCharPropInit = true;
-                }
-                if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                    break;
-            }
-            fCharacterCounter++;
-        }
-        hashcode = StringHasher.finishHash(hashcode);
-        int length = fCurrentOffset - offset;
-        int nameIndex = fCurrentChunk.addSymbol(offset, length, hashcode);
-        return nameIndex;
-    }
-
-    /**
-     *
-     */
-    public boolean scanExpectedName(char fastcheck, StringPool.CharArrayRange expectedName) throws Exception {
-        char[] expected = expectedName.chars;
-        int offset = expectedName.offset;
-        int len = expectedName.length;
-        int ch = fMostRecentChar;
-        for (int i = 0; i < len; i++) {
-            if (ch != expected[offset++]) {
-                skipPastNmtoken(fastcheck);
-                return false;
-            }
-            fCharacterCounter++;
-            ch = loadNextChar();
-        }
-        if (ch == fastcheck)
-            return true;
-        if (ch < 0x80) {
-            if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                return true;
-        } else {
-            if (!fCalledCharPropInit) {
-                XMLCharacterProperties.initCharFlags();
-                fCalledCharPropInit = true;
-            }
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                return true;
-        }
-        skipPastNmtoken(fastcheck);
-        return false;
-    }
-
-    /**
-     *
-     */
-    public void scanQName(char fastcheck, QName qname) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch < 0x80) {
-            if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0) {
-                qname.clear();
-                return;
-            }
-            if (ch == ':') {
-                qname.clear();
-                return;
-            }
-        } else {
-            if (!fCalledCharPropInit) {
-                XMLCharacterProperties.initCharFlags();
-                fCalledCharPropInit = true;
-            }
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0) {
-                qname.clear();
-                return;
-            }
-        }
-        int offset = fCurrentOffset;
-        fCharacterCounter++;
-        int hashcode = 0;
-        int prefixend = -1;
-        while (true) {
-            hashcode = StringHasher.hashChar(hashcode, ch);
-            ch = loadNextChar();
-            if (fastcheck == ch)
-                break;
-            if (ch < 0x80) {
-                if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                    break;
-                if (ch == ':') {
-                    if (prefixend != -1)
-                        break;
-                    prefixend = fCurrentOffset;
-                    //
-                    // We need to peek ahead one character.  If the next character is not a
-                    // valid initial name character, or is another colon, then we cannot meet
-                    // both the Prefix and LocalPart productions for the QName production,
-                    // which means that there is no Prefix and we need to terminate the QName
-                    // at the first colon.
-                    //
-                    CharDataChunk savedChunk = fCurrentChunk;
-                    int savedOffset = fCurrentOffset;
-                    int savedIndex = fCurrentIndex;
-                    ch = loadNextChar();
-                    fCurrentChunk = savedChunk;
-                    fCurrentOffset = savedOffset;
-                    fCurrentIndex = savedIndex;
-                    fMostRecentData = savedChunk.toCharArray();
-                    boolean lpok = true;
-                    if (ch < 0x80) {
-                        if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0 || ch == ':')
-                            lpok = false;
-                    } else {
-                        if (!fCalledCharPropInit) {
-                            XMLCharacterProperties.initCharFlags();
-                            fCalledCharPropInit = true;
-                        }
-                        if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
-                            lpok = false;
-                    }
-                    ch = ':';
-                    if (!lpok) {
-                        prefixend = -1;
-                        fMostRecentChar = ch;
-                        break;
-                    }
-                }
-            } else {
-                if (!fCalledCharPropInit) {
-                    XMLCharacterProperties.initCharFlags();
-                    fCalledCharPropInit = true;
-                }
-                if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                    break;
-            }
-            fCharacterCounter++;
-        }
-        hashcode = StringHasher.finishHash(hashcode);
-        int length = fCurrentOffset - offset;
-        qname.rawname = fCurrentChunk.addSymbol(offset, length, hashcode);
-        qname.prefix = prefixend == -1 ? -1 : addSymbol(offset, prefixend - offset);
-        qname.localpart = prefixend == -1 ? qname.rawname : addSymbol(prefixend + 1, fCurrentOffset - (prefixend + 1));
-        qname.uri = -1;
-
-    } // scanQName(char,QName)
-
-    //
-    // [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
-    //
-    /**
-     *
-     */
-    public int scanContent(QName element) throws Exception {
-        if (fCallClearPreviousChunk && fCurrentChunk.clearPreviousChunk())
-            fCallClearPreviousChunk = false;
-        int charDataOffset = fCurrentOffset;
-        int ch = fMostRecentChar;
-        if (ch < 0x80) {
-            switch (XMLCharacterProperties.fgAsciiWSCharData[ch]) {
-            case 0:
-                fCharacterCounter++;
-                ch = loadNextChar();
-                break;
-            case 1: // '<'
-                fCharacterCounter++;
-                ch = loadNextChar();
-                if (!fInCDSect) {
-                    return recognizeMarkup(ch);
-                }
-                break;
-            case 2: // '&'
-                fCharacterCounter++;
-                ch = loadNextChar();
-                if (!fInCDSect) {
-                    return recognizeReference(ch);
-                }
-                break;
-            case 3: // ']'
-                fCharacterCounter++;
-                ch = loadNextChar();
-                if (ch != ']')
-                    break;
-                {
-                    CharDataChunk dataChunk = fCurrentChunk;
-                    int index = fCurrentIndex;
-                    int offset = fCurrentOffset;
-                    if (loadNextChar() != '>') {
-                        fCurrentChunk = dataChunk;
-                        fCurrentIndex = index;
-                        fCurrentOffset = offset;
-                        fMostRecentData = dataChunk.toCharArray();
-                        fMostRecentChar = ']';
-                        break;
-                    }
-                }
-                loadNextChar();
-                fCharacterCounter += 2;
-                return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-            case 4: // invalid char
-                if (ch == 0 && atEOF(fCurrentOffset + 1)) {
-                    changeReaders();
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR; // REVISIT - not quite...
-                }
-                return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-            case 5:
-                do {
-                    if (ch == 0x0A) {
-                        fLinefeedCounter++;
-                        fCharacterCounter = 1;
-                    } else
-                        fCharacterCounter++;
-                    ch = loadNextChar();
-                } while (ch == 0x20 || ch == 0x09 || ch == 0x0A);
-                if (ch < 0x80) {
-                    switch (XMLCharacterProperties.fgAsciiCharData[ch]) {
-                    case 0:
-                        fCharacterCounter++;
-                        ch = loadNextChar();
-                        break;
-                    case 1: // '<'
-                        if (!fInCDSect) {
-                            callCharDataHandler(charDataOffset, fCurrentOffset, true);
-                            fCharacterCounter++;
-                            ch = loadNextChar();
-                            return recognizeMarkup(ch);
-                        }
-                        fCharacterCounter++;
-                        ch = loadNextChar();
-                        break;
-                    case 2: // '&'
-                        if (!fInCDSect) {
-                            callCharDataHandler(charDataOffset, fCurrentOffset, true);
-                            fCharacterCounter++;
-                            ch = loadNextChar();
-                            return recognizeReference(ch);
-                        }
-                        fCharacterCounter++;
-                        ch = loadNextChar();
-                        break;
-                    case 3: // ']'
-                        int endOffset = fCurrentOffset;
-                        ch = loadNextChar();
-                        if (ch != ']') {
-                            fCharacterCounter++;
-                            break;
-                        }
-                        {
-                            CharDataChunk dataChunk = fCurrentChunk;
-                            int index = fCurrentIndex;
-                            int offset = fCurrentOffset;
-                            if (loadNextChar() != '>') {
-                                fCurrentChunk = dataChunk;
-                                fCurrentIndex = index;
-                                fCurrentOffset = offset;
-                                fMostRecentData = dataChunk.toCharArray();
-                                fMostRecentChar = ']';
-                                fCharacterCounter++;
-                                break;
-                            }
-                        }
-                        loadNextChar();
-                        callCharDataHandler(charDataOffset, endOffset, true);
-                        fCharacterCounter += 3;
-                        return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-                    case 4: // invalid char
-                        callCharDataHandler(charDataOffset, fCurrentOffset, true);
-                        if (ch == 0 && atEOF(fCurrentOffset + 1)) {
-                            changeReaders();
-                            return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR; // REVISIT - not quite...
-                        }
-                        return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                    }
-                } else if (!skipMultiByteCharData(ch)) {
-                    callCharDataHandler(charDataOffset, fCurrentOffset, true);
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-                break;
-            }
-        } else if (!skipMultiByteCharData(ch)) {
-            return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-        }
-        ch = skipAsciiCharData();
-        while (true) {
-            if (ch < 0x80) {
-                switch (XMLCharacterProperties.fgAsciiCharData[ch]) {
-                case 0:
-                    fCharacterCounter++;
-                    ch = loadNextChar();
-                    break;
-                case 1: // '<'
-                    if (!fInCDSect) {
-                        callCharDataHandler(charDataOffset, fCurrentOffset, false);
-                        fCharacterCounter++;
-                        ch = loadNextChar();
-                        return recognizeMarkup(ch);
-                    }
-                    fCharacterCounter++;
-                    ch = loadNextChar();
-                    break;
-                case 2: // '&'
-                    if (!fInCDSect) {
-                        callCharDataHandler(charDataOffset, fCurrentOffset, false);
-                        fCharacterCounter++;
-                        ch = loadNextChar();
-                        return recognizeReference(ch);
-                    }
-                    fCharacterCounter++;
-                    ch = loadNextChar();
-                    break;
-                case 3: // ']'
-                    int endOffset = fCurrentOffset;
-                    ch = loadNextChar();
-                    if (ch != ']') {
-                        fCharacterCounter++;
-                        break;
-                    }
-                    CharDataChunk dataChunk = fCurrentChunk;
-                    int index = fCurrentIndex;
-                    int offset = fCurrentOffset;
-                    if (loadNextChar() != '>') {
-                        fCurrentChunk = dataChunk;
-                        fCurrentIndex = index;
-                        fCurrentOffset = offset;
-                        fMostRecentData = dataChunk.toCharArray();
-                        fMostRecentChar = ']';
-                        fCharacterCounter++;
-                        break;
-                    }
-                    loadNextChar();
-                    callCharDataHandler(charDataOffset, endOffset, false);
-                    fCharacterCounter += 3;
-                    return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-                case 4: // invalid char
-                    if (ch == 0x0A) {
-                        fLinefeedCounter++;
-                        fCharacterCounter = 1;
-                        ch = loadNextChar();
-                        break;
-                    }
-                    callCharDataHandler(charDataOffset, fCurrentOffset, false);
-                    if (ch == 0 && atEOF(fCurrentOffset + 1)) {
-                        changeReaders();
-                        return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR; // REVISIT - not quite...
-                    }
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-            } else {
-                if (!skipMultiByteCharData(ch)) {
-                    callCharDataHandler(charDataOffset, fCurrentOffset, false);
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-                ch = fMostRecentChar;
-            }
-        }
-    }
-
-    //
-    // Private data members
-    //
-    private static final char[] cdata_string = { 'C','D','A','T','A','[' };
-    private StringPool fStringPool = null;
-    private boolean fCallClearPreviousChunk = true;
-    private Vector fDeferredErrors = null;
-
-    //
-    // Private classes
-    //
-    private class DeferredError {
-        int errorCode;
-        Object[] args;
-        int offset;
-        DeferredError(int ec, Object[] a, int o) {
-            errorCode = ec;
-            args = a;
-            offset = o;
-        }
-    }
-
-    //
-    // Private methods
-    //
-
-    /*
-     * Return a result code for scanContent when the character data
-     * ends with a less-than character.
-     */
-    private int recognizeMarkup(int ch) throws Exception {
-        switch (ch) {
-        case 0:
-            return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-        case '?':
-            fCharacterCounter++;
-            loadNextChar();
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_PI;
-        case '!':
-            fCharacterCounter++;
-            ch = loadNextChar();
-            if (ch == 0) {
-                fCharacterCounter--;
-                fCurrentOffset--;
-                return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-            }
-            if (ch == '-') {
-                fCharacterCounter++;
-                ch = loadNextChar();
-                if (ch == 0) {
-                    fCharacterCounter -= 2;
-                    fCurrentOffset -= 2;
-                    return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-                }
-                if (ch == '-') {
-                    fCharacterCounter++;
-                    loadNextChar();
-                    return XMLEntityHandler.CONTENT_RESULT_START_OF_COMMENT;
-                }
-                break;
-            }
-            if (ch == '[') {
-                for (int i = 0; i < 6; i++) {
-                    fCharacterCounter++;
-                    ch = loadNextChar();
-                    if (ch == 0) {
-                        fCharacterCounter -= (2 + i);
-                        fCurrentOffset -= (2 + i);
-                        return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-                    }
-                    if (ch != cdata_string[i]) {
-                        return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
-                    }
-                }
-                fCharacterCounter++;
-                loadNextChar();
-                return XMLEntityHandler.CONTENT_RESULT_START_OF_CDSECT;
-            }
-            break;
-        case '/':
-            fCharacterCounter++;
-            loadNextChar();
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ETAG;
-        default:
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ELEMENT;
-        }
-        return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
-    }
-
-    /*
-     * Return a result code for scanContent when the character data
-     * ends with an ampersand character.
-     */
-    private int recognizeReference(int ch) throws Exception {
-        if (ch == 0) {
-            return XMLEntityHandler.CONTENT_RESULT_REFERENCE_END_OF_INPUT;
-        }
-        //
-        // [67] Reference ::= EntityRef | CharRef
-        // [68] EntityRef ::= '&' Name ';'
-        // [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
-        //
-        if (ch == '#') {
-            fCharacterCounter++;
-            loadNextChar();
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_CHARREF;
-        } else {
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ENTITYREF;
-        }
-    }
-
-    /*
-     * Skip over a multi-byte character.
-     */
-    private boolean skipMultiByteCharData(int ch) throws Exception {
-        if (ch < 0xD800) {
-            loadNextChar();
-            return true;
-        }
-        if (ch > 0xFFFD)
-            return false;
-        if (ch >= 0xDC00 && ch < 0xE000)
-            return false;
-        if (ch >= 0xD800 && ch < 0xDC00) {
-            CharDataChunk savedChunk = fCurrentChunk;
-            int savedIndex = fCurrentIndex;
-            int savedOffset = fCurrentOffset;
-            ch = loadNextChar();
-            if (ch < 0xDC00 || ch >= 0xE000) {
-                fCurrentChunk = savedChunk;
-                fCurrentIndex = savedIndex;
-                fCurrentOffset = savedOffset;
-                fMostRecentData = savedChunk.toCharArray();
-                fMostRecentChar = fMostRecentData[savedIndex] & 0xFFFF;
-                return false;
-            }
-        }
-        loadNextChar();
-        return true;
-    }
-
-    /*
-     * Skip over contiguous ascii character data.
-     *
-     * @return the character skipped
-     * @exception java.lang.Exception
-     */
-    private int skipAsciiCharData() throws Exception {
-        int ch = fMostRecentChar;
-        while (true) {
-            if (ch >= 0x80) {
-                return ch;
-            }
-            if (XMLCharacterProperties.fgAsciiCharData[ch] == 0) {
-                fCharacterCounter++;
-            } else if (ch == 0x0A) {
-                fLinefeedCounter++;
-                fCharacterCounter = 1;
-            } else {
-                return ch;
-            }
-            ch = loadNextChar();
-        }
-    }
-
-    /*
-     * Report character data to the parser through the entity handler interface.
-     *
-     * @param offset the offset of the start of the character data
-     * @param endOffset the offset of the end of the character data
-     * @param isWhitespace true if the character data is whitespace
-     * @exception java.lang.Exception
-     */
-    private void callCharDataHandler(int offset, int endOffset, boolean isWhitespace) throws Exception {
-
-        int length = endOffset - offset;
-        if (!fSendCharDataAsCharArray) {
-            int stringIndex = addString(offset, length);
-            if (isWhitespace)
-                fCharDataHandler.processWhitespace(stringIndex);
-            else
-                fCharDataHandler.processCharacters(stringIndex);
-            return;
-        }
-
-        CharDataChunk dataChunk = fCurrentChunk.chunkFor(offset);
-        int index = offset & CharDataChunk.CHUNK_MASK;
-        if (index + length <= CharDataChunk.CHUNK_SIZE) {
-            //
-            // All the chars are in the same chunk
-            //
-            if (length != 0) {
-                if (isWhitespace)
-                    fCharDataHandler.processWhitespace(dataChunk.toCharArray(), index, length);
-                else
-                    fCharDataHandler.processCharacters(dataChunk.toCharArray(), index, length);
-            }
-            return;
-        }
-
-        //
-        // The data is spread across chunks.
-        //
-        int count = length;
-        int nbytes = CharDataChunk.CHUNK_SIZE - index;
-        if (isWhitespace)
-            fCharDataHandler.processWhitespace(dataChunk.toCharArray(), index, nbytes);
-        else
-            fCharDataHandler.processCharacters(dataChunk.toCharArray(), index, nbytes);
-        count -= nbytes;
-
-        //
-        // Use each Chunk in turn until we are done.
-        //
-        do {
-            dataChunk = dataChunk.nextChunk();
-            if (dataChunk == null) {
-                throw new RuntimeException(new ImplementationMessages().createMessage(null, ImplementationMessages.INT_DCN, 0, null));
-            }
-            nbytes = count <= CharDataChunk.CHUNK_SIZE ? count : CharDataChunk.CHUNK_SIZE;
-            if (isWhitespace)
-                fCharDataHandler.processWhitespace(dataChunk.toCharArray(), 0, nbytes);
-            else
-                fCharDataHandler.processCharacters(dataChunk.toCharArray(), 0, nbytes);
-            count -= nbytes;
-        } while (count > 0);
-    }
-
-    /*
-     * Advance the reader's notion of where it is, moving on to the next chunk.
-     *
-     * @return The next character that will be processed.
-     * @exception java.lang.Exception
-     */
-    private int slowLoadNextChar() throws Exception {
-        fCallClearPreviousChunk = true;
-        if (fCurrentChunk.nextChunk() != null) {
-            fCurrentChunk = fCurrentChunk.nextChunk();
-            fCurrentIndex = 0;
-            fMostRecentData = fCurrentChunk.toCharArray();
-            return (fMostRecentChar = fMostRecentData[fCurrentIndex] & 0xFFFF);
-        } else {
-            fCurrentChunk = CharDataChunk.createChunk(fStringPool, fCurrentChunk);
-            fCurrentIndex = 0;
-            fFillIndex = 0;
-            loadFirstChar();
-            return fMostRecentChar;
-        }
-    }
-
-    /*
-     * Advance the reader's notion of where it is
-     *
-     * @return The next character that will be processed.
-     * @exception java.lang.Exception
-     */
-    private int loadNextChar() throws Exception {
-        fCurrentOffset++;
-        if (++fCurrentIndex == CharDataChunk.CHUNK_SIZE)
-            return slowLoadNextChar();
-        if (fCurrentIndex < fFillIndex)
-            return (fMostRecentChar = fMostRecentData[fCurrentIndex] & 0xFFFF);
-        return loadMoreChars();
-    }
-
-    /*
-     * Read the first character.
-     *
-     * @exception java.lang.Exception
-     */
-    private void loadFirstChar() throws Exception {
-        fMostRecentData = fCurrentChunk.toCharArray();
-        if (fMostRecentData == null) {
-            fMostRecentData = new char[CharDataChunk.CHUNK_SIZE];
-            fCurrentChunk.setCharArray(fMostRecentData);
-        }
-        loadMoreChars();
-    }
-
-    /*
-     * Fetch more characters.
-     *
-     * @exception java.lang.Exception
-     */
-    private boolean seenCR = false;
-    private int oweChar = -1;
-    private char[] inBuffer = new char[2];
-    private int loadMoreChars() throws Exception {
-        if (oweChar != -1) {
-            fMostRecentData[fFillIndex] = (char)oweChar;
-            fFillIndex++;
-            fLength++;
-            fMostRecentChar = oweChar;
-            oweChar = -1;
-            return fMostRecentChar;
-        } 
-        int result = -1;
-        try {
-            while (true) {
-                result = fCharacterStream.read(inBuffer, 0, 2);
-                switch (result) {
-                case -1:
-                    break;
-                case 0:
-                    continue;
-                case 1:
-                    result = inBuffer[0];
-                    if (seenCR) {
-                        seenCR = false;
-                        if (result == 0x0A)
-                            continue;
-                    }
-                    if (result == 0x0D) {
-                        seenCR = true;
-                        result = 0x0A;
-                    }
-                    fMostRecentChar = (fMostRecentData[fFillIndex] = (char)result);
-                    fFillIndex++;
-                    fLength++;
-                    return fMostRecentChar;
-                case 2:
-                    result = inBuffer[0];
-                    boolean readchar2 = false;
-                    if (seenCR) {
-                        seenCR = false;
-                        if (result == 0x0A) {
-                            result = inBuffer[1];
-                            readchar2 = true;
-                        }
-                    }
-                    if (result == 0x0D) {
-                        seenCR = true;
-                        result = 0x0A;
-                    }
-                    fMostRecentChar = (fMostRecentData[fFillIndex] = (char)result);
-                    fFillIndex++;
-                    fLength++;
-                    if (!readchar2) {
-                        result = inBuffer[1];
-                        if (seenCR) {
-                            seenCR = false;
-                            if (result == 0x0A)
-                                return fMostRecentChar;
-                        }
-                        if (result == 0x0D) {
-                            seenCR = true;
-                            result = 0x0A;
-                        }
-                        oweChar = result;
-                    }
-                    return fMostRecentChar;
-                }
-                break;
-            }
-        } catch (java.io.IOException ex) {
-        }
-        //
-        // We have reached the end of the stream.
-        //
-        try {
-            fCharacterStream.close();
-        } catch (java.io.IOException ex) {
-        }
-        fCharacterStream = null;
-        fMostRecentChar = (fMostRecentData[fFillIndex] = 0);
-        return 0;
-    }
-
-    /*
-     * Would the reader be at end of file at a given offset?
-     *
-     * @param offset the offset to test for being at EOF
-     * @return true if being at offset would mean being at or beyond EOF
-     */
-    private boolean atEOF(int offset) {
-        return (offset > fLength);
-    }
-
-    //
-    //
-    //
-    protected Reader fCharacterStream = null;
-    protected CharDataChunk fCurrentChunk = null;
-    protected int fCurrentIndex = 0;
-    protected int fFillIndex = 0;
-    protected char[] fMostRecentData = null;
-    protected int fMostRecentChar = 0;
-    protected int fLength = 0;
-    protected boolean fCalledCharPropInit = false;
-
-}
diff --git a/src/org/apache/xerces/readers/StringReader.java b/src/org/apache/xerces/readers/StringReader.java
deleted file mode 100644
index 3bbcebe..0000000
--- a/src/org/apache/xerces/readers/StringReader.java
+++ /dev/null
@@ -1,987 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.utils.XMLCharacterProperties;
-
-import org.xml.sax.Locator;
-import org.xml.sax.InputSource;
-import java.io.IOException;
-
-/**
- * Reader for processing internal entity replacement text.
- * <p>
- * This reader processes data contained within strings kept
- * in the string pool.  It provides the support for both
- * general and parameter entities.  The location support
- * as we are processing the replacement text is somewhat
- * poor and needs to be updated when "nested locations"
- * have been implemented.
- * <p>
- * For efficiency, we return instances of this class to a
- * free list and reuse those instances to process other
- * strings.
- *
- * @version $id$
- */
-final class StringReader extends XMLEntityReader {
-    /**
-     * Allocate a string reader
-     *
-     * @param entityHandler The current entity handler.
-     * @param errorReporter The current error reporter.
-     * @param sendCharDataAsCharArray true if char data should be reported using
-     *                                char arrays instead of string handles.
-     * @param lineNumber The line number to return as our position.
-     * @param columnNumber The column number to return as our position.
-     * @param stringHandle The StringPool handle for the data to process.
-     * @param stringPool The string pool.
-     * @param addEnclosingSpaces If true, treat the data to process as if
-     *                           there were a leading and trailing space
-     *                           character enclosing the string data.
-     * @return The reader that will process the string data.
-     */
-    public static StringReader createStringReader(XMLEntityHandler entityHandler,
-                                                  XMLErrorReporter errorReporter,
-                                                  boolean sendCharDataAsCharArray,
-                                                  int lineNumber,
-                                                  int columnNumber,
-                                                  int stringHandle,
-                                                  StringPool stringPool,
-                                                  boolean addEnclosingSpaces)
-    {
-        StringReader reader = null;
-        synchronized (StringReader.class) {
-            reader = fgFreeReaders;
-            if (reader == null) {
-                return new StringReader(entityHandler, errorReporter, sendCharDataAsCharArray, lineNumber, columnNumber,
-                                        stringHandle, stringPool, addEnclosingSpaces);
-            }
-            fgFreeReaders = reader.fNextFreeReader;
-        }
-        reader.init(entityHandler, errorReporter, sendCharDataAsCharArray, lineNumber, columnNumber,
-                    stringHandle, stringPool, addEnclosingSpaces);
-        return reader;
-    }
-    //
-    //
-    //
-    private StringReader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter,
-                         boolean sendCharDataAsCharArray, int lineNumber, int columnNumber,
-                         int stringHandle, StringPool stringPool, boolean addEnclosingSpaces)
-    {
-        super(entityHandler, errorReporter, sendCharDataAsCharArray, lineNumber, columnNumber);
-        fStringPool = stringPool;
-        fData = fStringPool.toString(stringHandle);
-        fCurrentOffset = 0;
-        fEndOffset = fData.length();
-        if (addEnclosingSpaces) {
-            fMostRecentChar = ' ';
-            fCurrentOffset--;
-            oweTrailingSpace = hadTrailingSpace = true;
-        } else {
-            fMostRecentChar = fEndOffset == 0 ? -1 : fData.charAt(0);
-        }
-    }
-    private void init(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter,
-                      boolean sendCharDataAsCharArray, int lineNumber, int columnNumber,
-                      int stringHandle, StringPool stringPool, boolean addEnclosingSpaces)
-    {
-        super.init(entityHandler, errorReporter, sendCharDataAsCharArray, lineNumber, columnNumber);
-        fStringPool = stringPool;
-        fData = fStringPool.toString(stringHandle);
-        fCurrentOffset = 0;
-        fEndOffset = fData.length();
-        fNextFreeReader = null;
-        if (addEnclosingSpaces) {
-            fMostRecentChar = ' ';
-            fCurrentOffset--;
-            oweTrailingSpace = hadTrailingSpace = true;
-        } else {
-            fMostRecentChar = fEndOffset == 0 ? -1 : fData.charAt(0);
-            oweTrailingSpace = hadTrailingSpace = false;
-        }
-    }
-    //
-    //
-    //
-    public int addString(int offset, int length) {
-        if (length == 0)
-            return 0;
-        return fStringPool.addString(fData.substring(offset, offset + length));
-    }
-    //
-    //
-    //
-    public int addSymbol(int offset, int length) {
-        if (length == 0)
-            return 0;
-        return fStringPool.addSymbol(fData.substring(offset, offset + length));
-    }
-    //
-    //
-    //
-    public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length) {
-        boolean addSpace = false;
-        for (int i = 0; i < length; i++) {
-            try {
-                charBuffer.append(fData.charAt(offset++));
-            } catch (StringIndexOutOfBoundsException ex) {
-                if (offset == fEndOffset + 1 && hadTrailingSpace) {
-                    charBuffer.append(' ');
-                } else {
-                    System.err.println("StringReader.append()");
-                    throw ex;
-                }
-            }
-        }
-    }
-    //
-    //
-    //
-    private int loadNextChar() {
-        if (++fCurrentOffset >= fEndOffset) {
-            if (oweTrailingSpace) {
-                oweTrailingSpace = false;
-                fMostRecentChar = ' ';
-            } else {
-                fMostRecentChar = -1;
-            }
-        } else {
-            fMostRecentChar = fData.charAt(fCurrentOffset);
-        }
-        return fMostRecentChar;
-    }
-    //
-    //
-    //
-    public XMLEntityHandler.EntityReader changeReaders() throws Exception {
-        XMLEntityHandler.EntityReader nextReader = super.changeReaders();
-        synchronized (StringReader.class) {
-            fNextFreeReader = fgFreeReaders;
-            fgFreeReaders = this;
-        }
-        return nextReader;
-    }
-    //
-    //
-    //
-    public boolean lookingAtChar(char chr, boolean skipPastChar) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch != chr) {
-            if (ch == -1) {
-                return changeReaders().lookingAtChar(chr, skipPastChar);
-            }
-            return false;
-        }
-        if (skipPastChar) {
-            if (++fCurrentOffset >= fEndOffset) {
-                if (oweTrailingSpace) {
-                    oweTrailingSpace = false;
-                    fMostRecentChar = ' ';
-                } else {
-                    fMostRecentChar = -1;
-                }
-            } else {
-                fMostRecentChar = fData.charAt(fCurrentOffset);
-            }
-        }
-        return true;
-    }
-    //
-    //
-    //
-    public boolean lookingAtValidChar(boolean skipPastChar) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch < 0xD800) {
-            if (ch < 0x20 && ch != 0x09 && ch != 0x0A && ch != 0x0D) {
-                if (ch == -1)
-                    return changeReaders().lookingAtValidChar(skipPastChar);
-                return false;
-            }
-            if (skipPastChar) {
-                if (++fCurrentOffset >= fEndOffset) {
-                    if (oweTrailingSpace) {
-                        oweTrailingSpace = false;
-                        fMostRecentChar = ' ';
-                    } else {
-                        fMostRecentChar = -1;
-                    }
-                } else {
-                    fMostRecentChar = fData.charAt(fCurrentOffset);
-                }
-            }
-            return true;
-        }
-        if (ch > 0xFFFD) {
-            return false;
-        }
-        if (ch < 0xDC00) {
-            if (fCurrentOffset + 1 >= fEndOffset) {
-                return false;
-            }
-            ch = fData.charAt(fCurrentOffset + 1);
-            if (ch < 0xDC00 || ch >= 0xE000) {
-                return false;
-            } else if (!skipPastChar) {
-                return true;
-            } else {
-                fCurrentOffset++;
-            }
-        } else if (ch < 0xE000) {
-            return false;
-        }
-        if (skipPastChar) {
-            if (++fCurrentOffset >= fEndOffset) {
-                if (oweTrailingSpace) {
-                    oweTrailingSpace = false;
-                    fMostRecentChar = ' ';
-                } else {
-                    fMostRecentChar = -1;
-                }
-            } else {
-                fMostRecentChar = fData.charAt(fCurrentOffset);
-            }
-        }
-        return true;
-    }
-    //
-    //
-    //
-    public boolean lookingAtSpace(boolean skipPastChar) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch > 0x20)
-            return false;
-        if (ch == 0x20 || ch == 0x0A || ch == 0x0D || ch == 0x09) {
-            if (skipPastChar) {
-                loadNextChar();
-            }
-            return true;
-        }
-        if (ch == -1) {
-            return changeReaders().lookingAtSpace(skipPastChar);
-        }
-        return false;
-    }
-    //
-    //
-    //
-    public void skipToChar(char chr) throws Exception {
-        //
-        // REVISIT - this will skip invalid characters without reporting them.
-        //
-        int ch = fMostRecentChar;
-        while (true) {
-            if (ch == chr)
-                return;
-            if (ch == -1) {
-                changeReaders().skipToChar(chr);
-                return;
-            }
-            ch = loadNextChar();
-        }
-    }
-    //
-    //
-    //
-    public void skipPastSpaces() throws Exception {
-        int ch = fMostRecentChar;
-        if (ch == -1) {
-            changeReaders().skipPastSpaces();
-            return;
-        }
-        while (true) {
-            if (ch > 0x20 || (ch != 0x20 && ch != 0x0A && ch != 0x09 && ch != 0x0D)) {
-                fMostRecentChar = ch;
-                return;
-            }
-            if (++fCurrentOffset >= fEndOffset) {
-                changeReaders().skipPastSpaces();
-                return;
-            }
-            ch = fData.charAt(fCurrentOffset);
-        }
-    }
-    //
-    //
-    //
-    public void skipPastName(char fastcheck) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch < 0x80) {
-            if (ch == -1 || XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0)
-                return;
-        } else {
-            if (!fCalledCharPropInit) {
-                XMLCharacterProperties.initCharFlags();
-                fCalledCharPropInit = true;
-            }
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
-                return;
-        }
-        while (true) {
-            ch = loadNextChar();
-            if (fastcheck == ch)
-                return;
-            if (ch < 0x80) {
-                if (ch == -1 || XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                    return;
-            } else {
-                if (!fCalledCharPropInit) {
-                    XMLCharacterProperties.initCharFlags();
-                    fCalledCharPropInit = true;
-                }
-                if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                    return;
-            }
-        }
-    }
-    //
-    //
-    //
-    public void skipPastNmtoken(char fastcheck) throws Exception {
-        int ch = fMostRecentChar;
-        while (true) {
-            if (fastcheck == ch)
-                return;
-            if (ch < 0x80) {
-                if (ch == -1 || XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                    return;
-            } else {
-                if (!fCalledCharPropInit) {
-                    XMLCharacterProperties.initCharFlags();
-                    fCalledCharPropInit = true;
-                }
-                if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                    return;
-            }
-            ch = loadNextChar();
-        }
-    }
-    //
-    //
-    //
-    public boolean skippedString(char[] s) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch != s[0]) {
-            if (ch == -1)
-                return changeReaders().skippedString(s);
-            return false;
-        }
-        if (fCurrentOffset + s.length > fEndOffset)
-            return false;
-        for (int i = 1; i < s.length; i++) {
-            if (fData.charAt(fCurrentOffset + i) != s[i])
-                return false;
-        }
-        fCurrentOffset += (s.length - 1);
-        loadNextChar();
-        return true;
-    }
-    //
-    //
-    //
-    public int scanInvalidChar() throws Exception {
-        int ch = fMostRecentChar;
-        if (ch == -1)
-            return changeReaders().scanInvalidChar();
-        loadNextChar();
-        return ch;
-    }
-    //
-    //
-    //
-    public int scanCharRef(boolean hex) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch == -1)
-            return changeReaders().scanCharRef(hex);
-        int num = 0;
-        if (hex) {
-            if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
-                return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-            num = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
-        } else {
-            if (ch < '0' || ch > '9')
-                return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-            num = ch - '0';
-        }
-        boolean toobig = false;
-        while (true) {
-            ch = loadNextChar();
-            if (ch == -1)
-                return XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED;
-            if (hex) {
-                if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
-                    break;
-            } else {
-                if (ch < '0' || ch > '9')
-                    break;
-            }
-            if (hex) {
-                int dig = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
-                num = (num << 4) + dig;
-            } else {
-                int dig = ch - '0';
-                num = (num * 10) + dig;
-            }
-            if (num > 0x10FFFF) {
-                toobig = true;
-                num = 0;
-            }
-        }
-        if (ch != ';')
-            return XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED;
-        loadNextChar();
-        if (toobig)
-            return XMLEntityHandler.CHARREF_RESULT_OUT_OF_RANGE;
-        return num;
-    }
-    //
-    //
-    //
-    public int scanStringLiteral() throws Exception {
-        boolean single;
-        if (!(single = lookingAtChar('\'', true)) && !lookingAtChar('\"', true)) {
-            return XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED;
-        }
-        int offset = fCurrentOffset;
-        char qchar = single ? '\'' : '\"';
-        while (!lookingAtChar(qchar, false)) {
-            if (!lookingAtValidChar(true)) {
-                return XMLEntityHandler.STRINGLIT_RESULT_INVALID_CHAR;
-            }
-        }
-        int stringIndex = addString(offset, fCurrentOffset - offset);
-        lookingAtChar(qchar, true); // move past qchar
-        return stringIndex;
-    }
-    //
-    // [10] AttValue ::= '"' ([^<&"] | Reference)* '"'
-    //                   | "'" ([^<&'] | Reference)* "'"
-    //
-    public int scanAttValue(char qchar, boolean asSymbol) throws Exception
-    {
-        int offset = fCurrentOffset;
-        while (true) {
-            if (lookingAtChar(qchar, false)) {
-                break;
-            }
-            if (lookingAtChar(' ', true)) {
-                continue;
-            }
-            if (lookingAtSpace(false)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_COMPLEX;
-            }
-            if (lookingAtChar('&', false)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_COMPLEX;
-            }
-            if (lookingAtChar('<', false)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_LESSTHAN;
-            }
-            if (!lookingAtValidChar(true)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_INVALID_CHAR;
-            }
-        }
-        int result = asSymbol ? addSymbol(offset, fCurrentOffset - offset) : addString(offset, fCurrentOffset - offset);
-        lookingAtChar(qchar, true);
-        return result;
-    }
-    //
-    //  [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
-    //                      | "'" ([^%&'] | PEReference | Reference)* "'"
-    //
-    // The values in the following table are defined as:
-    //
-    //      0 - not special
-    //      1 - quote character
-    //      2 - reference
-    //      3 - peref
-    //      4 - invalid
-    //
-    public static final byte fgAsciiEntityValueChar[] = {
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 0, 4, 4,
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-        0, 0, 1, 0, 0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, // '\"', '%', '&', '\''
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    };
-    public int scanEntityValue(int qchar, boolean createString) throws Exception
-    {
-        int offset = fCurrentOffset;
-        int ch = fMostRecentChar;
-        while (true) {
-            if (ch == -1) {
-                changeReaders(); // do not call next reader, our caller may need to change the parameters
-                return XMLEntityHandler.ENTITYVALUE_RESULT_END_OF_INPUT;
-            }
-            if (ch < 0x80) {
-                switch (fgAsciiEntityValueChar[ch]) {
-                case 1: // quote char
-                    if (ch == qchar) {
-                        if (!createString)
-                            return XMLEntityHandler.ENTITYVALUE_RESULT_FINISHED;
-                        int length = fCurrentOffset - offset;
-                        int result = length == 0 ? StringPool.EMPTY_STRING : addString(offset, length);
-                        loadNextChar();
-                        return result;
-                    }
-                    // the other quote character is not special
-                    // fall through
-                case 0: // non-special char
-                    if (++fCurrentOffset >= fEndOffset) {
-                        if (oweTrailingSpace) {
-                            oweTrailingSpace = false;
-                            ch = fMostRecentChar = ' ';
-                        } else {
-                            ch = fMostRecentChar = -1;
-                        }
-                    } else {
-                        ch = fMostRecentChar = fData.charAt(fCurrentOffset);
-                    }
-                    continue;
-                case 2: // reference
-                    return XMLEntityHandler.ENTITYVALUE_RESULT_REFERENCE;
-                case 3: // peref
-                    return XMLEntityHandler.ENTITYVALUE_RESULT_PEREF;
-                case 4: // invalid
-                    return XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR;
-                }
-            } else if (ch < 0xD800) {
-                ch = loadNextChar();
-            } else if (ch >= 0xE000 && (ch <= 0xFFFD || (ch >= 0x10000 && ch <= 0x10FFFF))) {
-                //
-                // REVISIT - needs more code to check surrogates.
-                //
-                ch = loadNextChar();
-            } else {
-                return XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR;
-            }
-        }
-    }
-    //
-    //
-    //
-    public boolean scanExpectedName(char fastcheck, StringPool.CharArrayRange expectedName) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch == -1) {
-            return changeReaders().scanExpectedName(fastcheck, expectedName);
-        }
-        if (!fCalledCharPropInit) {
-            XMLCharacterProperties.initCharFlags();
-            fCalledCharPropInit = true;
-        }
-        int nameOffset = fCurrentOffset;
-        if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
-            return false;
-        while (true) {
-            ch = loadNextChar();
-            if (fastcheck == ch)
-                break;
-            if (ch == -1)
-                break;
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                break;
-        }
-        int nameIndex = fStringPool.addSymbol(fData.substring(nameOffset, fCurrentOffset));
-        // DEFECT !! check name against expected name
-
-        return true;
-    }
-    //
-    //
-    //
-    public void scanQName(char fastcheck, QName qname) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch == -1) {
-            changeReaders().scanQName(fastcheck, qname);
-            return;
-        }
-        if (!fCalledCharPropInit) {
-            XMLCharacterProperties.initCharFlags();
-            fCalledCharPropInit = true;
-        }
-        int nameOffset = fCurrentOffset;
-        if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0) {
-            qname.clear();
-            return;
-        }
-        while (true) {
-            ch = loadNextChar();
-            if (fastcheck == ch)
-                break;
-            if (ch == -1)
-                break;
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                break;
-        }
-
-        qname.clear();
-        qname.rawname = fStringPool.addSymbol(fData.substring(nameOffset, fCurrentOffset));
-       
-        int index = fData.indexOf(':', nameOffset);
-        if (index != -1) {
-            qname.prefix = fStringPool.addSymbol(fData.substring(nameOffset, index));
-            int indexOfSpaceChar = fData.indexOf( ' ', index + 1 );//one past : look for blank
-            String localPart;
-            if( indexOfSpaceChar != -1 ){//found one
-                localPart = fData.substring(index+1, indexOfSpaceChar );
-                qname.localpart  = fStringPool.addSymbol(localPart);
-            } else{//then get up to end of String
-                int lenfData     = fData.length();
-                localPart = fData.substring( index + 1, lenfData );
-                qname.localpart  = fStringPool.addSymbol(localPart);
-            }
-            qname.localpart  = fStringPool.addSymbol(localPart);
-        }
-        else {
-            qname.localpart  = qname.rawname;
-        }
-
-    } // scanQName(char,QName)
-
-    //
-    //
-    //
-    public int scanName(char fastcheck) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch == -1) {
-            return changeReaders().scanName(fastcheck);
-        }
-        if (!fCalledCharPropInit) {
-            XMLCharacterProperties.initCharFlags();
-            fCalledCharPropInit = true;
-        }
-        int nameOffset = fCurrentOffset;
-        if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
-            return -1;
-        while (true) {
-            if (++fCurrentOffset >= fEndOffset) {
-                if (oweTrailingSpace) {
-                    oweTrailingSpace = false;
-                    fMostRecentChar = ' ';
-                } else {
-                    fMostRecentChar = -1;
-                }
-                break;
-            }
-            ch = fMostRecentChar = fData.charAt(fCurrentOffset);
-            if (fastcheck == ch)
-                break;
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                break;
-        }
-        int nameIndex = fStringPool.addSymbol(fData.substring(nameOffset, fCurrentOffset));
-        return nameIndex;
-    }
-    //
-    // There are no leading/trailing space checks here because scanContent cannot
-    // be called on a parameter entity reference value.
-    //
-    private int recognizeMarkup(int ch) throws Exception {
-        if (ch == -1) {
-            return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-        }
-        switch (ch) {
-        case '?':
-            loadNextChar();
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_PI;
-        case '!':
-            ch = loadNextChar();
-            if (ch == -1) {
-                fCurrentOffset -= 2;
-                loadNextChar();
-                return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-            }
-            if (ch == '-') {
-                ch = loadNextChar();
-                if (ch == -1) {
-                    fCurrentOffset -= 3;
-                    loadNextChar();
-                    return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-                }
-                if (ch == '-') {
-                    loadNextChar();
-                    return XMLEntityHandler.CONTENT_RESULT_START_OF_COMMENT;
-                }
-                break;
-            }
-            if (ch == '[') {
-                for (int i = 0; i < 6; i++) {
-                    ch = loadNextChar();
-                    if (ch == -1) {
-                        fCurrentOffset -= (3 + i);
-                        loadNextChar();
-                        return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-                    }
-                    if (ch != cdata_string[i]) {
-                        return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
-                    }
-                }
-                loadNextChar();
-                return XMLEntityHandler.CONTENT_RESULT_START_OF_CDSECT;
-            }
-            break;
-        case '/':
-            loadNextChar();
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ETAG;
-        default:
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ELEMENT;
-        }
-        return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
-    }
-    private int recognizeReference(int ch) throws Exception {
-        if (ch == -1) {
-            return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-        }
-        //
-        // [67] Reference ::= EntityRef | CharRef
-        // [68] EntityRef ::= '&' Name ';'
-        // [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
-        //
-        if (ch == '#') {
-            loadNextChar();
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_CHARREF;
-        } else {
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ENTITYREF;
-        }
-    }
-    public int scanContent(QName element) throws Exception {
-        int ch = fMostRecentChar;
-        if (ch == -1) {
-            return changeReaders().scanContent(element);
-        }
-        int offset = fCurrentOffset;
-        if (ch < 0x80) {
-            switch (XMLCharacterProperties.fgAsciiWSCharData[ch]) {
-            case 0:
-                ch = loadNextChar();
-                break;
-            case 1:
-                ch = loadNextChar();
-                if (!fInCDSect) {
-                    return recognizeMarkup(ch);
-                }
-                break;
-            case 2:
-                ch = loadNextChar();
-                if (!fInCDSect) {
-                    return recognizeReference(ch);
-                }
-                break;
-            case 3:
-                ch = loadNextChar();
-                if (ch == ']' && fCurrentOffset + 1 < fEndOffset && fData.charAt(fCurrentOffset + 1) == '>') {
-                    loadNextChar();
-                    loadNextChar();
-                    return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-                }
-                break;
-            case 4:
-                return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-            case 5:
-                do {
-                    ch = loadNextChar();
-                    if (ch == -1) {
-                        callCharDataHandler(offset, fEndOffset, true);
-                        return changeReaders().scanContent(element);
-                    }
-                } while (ch == 0x20 || ch == 0x0A || ch == 0x0D || ch == 0x09);
-                if (ch < 0x80) {
-                    switch (XMLCharacterProperties.fgAsciiCharData[ch]) {
-                    case 0:
-                        ch = loadNextChar();
-                        break;
-                    case 1:
-                        ch = loadNextChar();
-                        if (!fInCDSect) {
-                            callCharDataHandler(offset, fCurrentOffset - 1, true);
-                            return recognizeMarkup(ch);
-                        }
-                        break;
-                    case 2:
-                        ch = loadNextChar();
-                        if (!fInCDSect) {
-                            callCharDataHandler(offset, fCurrentOffset - 1, true);
-                            return recognizeReference(ch);
-                        }
-                        break;
-                    case 3:
-                        ch = loadNextChar();
-                        if (ch == ']' && fCurrentOffset + 1 < fEndOffset && fData.charAt(fCurrentOffset + 1) == '>') {
-                            callCharDataHandler(offset, fCurrentOffset - 1, true);
-                            loadNextChar();
-                            loadNextChar();
-                            return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-                        }
-                        break;
-                    case 4:
-                        callCharDataHandler(offset, fCurrentOffset, true);
-                        return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                    }
-                } else {
-                    if (ch == 0xFFFE || ch == 0xFFFF) {
-                        callCharDataHandler(offset, fCurrentOffset, true);
-                        return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                    }
-                    ch = loadNextChar();
-                }
-            }
-        } else {
-            if (ch == 0xFFFE || ch == 0xFFFF) {
-                callCharDataHandler(offset, fCurrentOffset, false);
-                return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-            }
-            ch = loadNextChar();
-        }
-        while (true) {
-            if (ch == -1) {
-                callCharDataHandler(offset, fEndOffset, false);
-                return changeReaders().scanContent(element);
-            }
-            if (ch >= 0x80)
-                break;
-            if (XMLCharacterProperties.fgAsciiCharData[ch] != 0)
-                break;
-            ch = loadNextChar();
-        }
-        while (true) { // REVISIT - EOF check ?
-            if (ch < 0x80) {
-                switch (XMLCharacterProperties.fgAsciiCharData[ch]) {
-                case 0:
-                    ch = loadNextChar();
-                    break;
-                case 1:
-                    ch = loadNextChar();
-                    if (!fInCDSect) {
-                        callCharDataHandler(offset, fCurrentOffset - 1, false);
-                        return recognizeMarkup(ch);
-                    }
-                    break;
-                case 2:
-                    ch = loadNextChar();
-                    if (!fInCDSect) {
-                        callCharDataHandler(offset, fCurrentOffset - 1, false);
-                        return recognizeReference(ch);
-                    }
-                    break;
-                case 3:
-                    ch = loadNextChar();
-                    if (ch == ']' && fCurrentOffset + 1 < fEndOffset && fData.charAt(fCurrentOffset + 1) == '>') {
-                        callCharDataHandler(offset, fCurrentOffset - 1, false);
-                        loadNextChar();
-                        loadNextChar();
-                        return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-                    }
-                    break;
-                case 4:
-                    callCharDataHandler(offset, fCurrentOffset, false);
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-            } else {
-                if (ch == 0xFFFE || ch == 0xFFFF) {
-                    callCharDataHandler(offset, fCurrentOffset, false);
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-                ch = loadNextChar();
-            }
-            if (ch == -1) {
-                callCharDataHandler(offset, fCurrentOffset, false);
-                return changeReaders().scanContent(element);
-            }
-        }
-    }
-    //
-    //
-    //
-    private void callCharDataHandler(int offset, int endOffset, boolean isWhitespace) throws Exception {
-        int length = endOffset - offset;
-        if (!fSendCharDataAsCharArray) {
-            int stringIndex = addString(offset, length);
-            if (isWhitespace)
-                fCharDataHandler.processWhitespace(stringIndex);
-            else
-                fCharDataHandler.processCharacters(stringIndex);
-            return;
-        }
-        if (isWhitespace)
-            fCharDataHandler.processWhitespace(fData.toCharArray(), offset, length);
-        else
-            fCharDataHandler.processCharacters(fData.toCharArray(), offset, length);
-    }
-    //
-    //
-    //
-    private static final char[] cdata_string = { 'C','D','A','T','A','[' };
-    //
-    //
-    //
-    private StringPool fStringPool = null;
-    private String fData = null;
-    private int fEndOffset;
-    private boolean hadTrailingSpace = false;
-    private boolean oweTrailingSpace = false;
-    private int fMostRecentChar;
-    private StringReader fNextFreeReader = null;
-    private static StringReader fgFreeReaders = null;
-    private boolean fCalledCharPropInit = false;
-}
diff --git a/src/org/apache/xerces/readers/UCSReader.java b/src/org/apache/xerces/readers/UCSReader.java
deleted file mode 100644
index 448fb8a..0000000
--- a/src/org/apache/xerces/readers/UCSReader.java
+++ /dev/null
@@ -1,953 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.ChunkyByteArray;
-import org.apache.xerces.utils.ChunkyCharArray;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringHasher;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.utils.XMLCharacterProperties;
-import java.io.IOException;
-
-/**
- * Reader for UCS-2 and UCS-4 encodings.
- * <p>
- * This reader is created by the UCSRecognizer class when it decides that the
- * byte stream is encoded in a format supported by this class.  This class
- * was intended to be another example of an encoding sensitive reader that
- * could take advantage of the system design to improve performance and reduce
- * resource consumption, but the actual performance tuning remains to be done.
- *
- * @version $Id$
- */
-final class UCSReader extends XMLEntityReader implements StringPool.StringProducer {
-
-    //
-    // Constants
-    //
-
-    // debugging
-    
-    /** Set to true to debug UTF-16, big-endian. */
-    private static final boolean DEBUG_UTF16_BIG = false;
-
-    //
-    // Scanner encoding enumeration
-    //
-    static final int
-        E_UCS4B = 0,            // UCS-4 big endian
-        E_UCS4L = 1,            // UCS-4 little endian
-        E_UCS2B = 2,            // UCS-2 big endian with byte order mark
-        E_UCS2L = 3,            // UCS-2 little endian with byte order mark
-        E_UCS2B_NOBOM = 4,      // UCS-2 big endian without byte order mark
-        E_UCS2L_NOBOM = 5;      // UCS-2 little endian without byte order mark
-    //
-    //
-    //
-    private ChunkyByteArray fData = null;
-    private int fEncoding = -1;
-    private StringPool fStringPool = null;
-    private int fBytesPerChar = -1;
-    private boolean fBigEndian = true;
-    private ChunkyCharArray fStringCharArray = null;
-    private boolean fCalledCharPropInit = false;
-    //
-    //
-    //
-    UCSReader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter, boolean sendCharDataAsCharArray, ChunkyByteArray data, int encoding, StringPool stringPool) throws Exception {
-        super(entityHandler, errorReporter, sendCharDataAsCharArray);
-        fCurrentOffset = (encoding == E_UCS2B || encoding == E_UCS2L) ? 2 : 0;
-        fData = data;
-        fEncoding = encoding;
-        fStringPool = stringPool;
-        fBytesPerChar = (fEncoding == E_UCS4B || fEncoding == E_UCS4L) ? 4 : 2;
-        fBigEndian = fEncoding == E_UCS4B || fEncoding == E_UCS2B || fEncoding == E_UCS2B_NOBOM;
-    }
-    //
-    //
-    //
-    private int getChar(int offset) throws IOException {
-        int b0 = fData.byteAt(offset++) & 0xff;
-        if (b0 == 0xff && fData.atEOF(offset))
-            return -1;
-        int b1 = fData.byteAt(offset++) & 0xff;
-        if (fBytesPerChar == 4) {
-            int b2 = fData.byteAt(offset++) & 0xff;
-            int b3 = fData.byteAt(offset++) & 0xff;
-            if (fBigEndian)
-                return (b0<<24)+(b1<<16)+(b2<<8)+b3;
-            else
-                return (b3<<24)+(b2<<16)+(b1<<8)+b0;
-        } else {
-            if (fBigEndian)
-                return (b0<<8)+b1;
-            else
-                return (b1<<8)+b0;
-        }
-    }
-    /**
-     *
-     */
-    public int addString(int offset, int length) {
-        if (length == 0)
-            return 0;
-        return fStringPool.addString(this, offset, length);
-    }
-    /**
-     *
-     */
-    public int addSymbol(int offset, int length) {
-        if (length == 0)
-            return 0;
-        return fStringPool.addSymbol(this, offset, length, getHashcode(offset, length));
-    }
-    //
-    //
-    //
-    public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length) {
-        int endOffset = offset + length;
-        while (offset < endOffset) {
-            int ch;
-            try {
-                ch = getChar(offset);
-            }
-            catch (IOException ex) {
-                ch = 0; // REVISIT
-            }
-            charBuffer.append((char)ch);
-            offset += fBytesPerChar;
-        }
-    }
-    //
-    //
-    //
-    public void releaseString(int offset, int length) {
-        // nothing to do...
-    }
-    //
-    //
-    //
-    public String toString(int offset, int length) {
-        //
-        // REVISIT - we need to cache this operation !!
-        //
-        if (fStringCharArray == null)
-            fStringCharArray = new ChunkyCharArray(fStringPool);
-        int newOffset = fStringCharArray.length();
-        append(fStringCharArray, offset, length);
-        int newLength = fStringCharArray.length() - newOffset;
-        int stringIndex = fStringCharArray.addString(newOffset, newLength);
-        return fStringPool.toString(stringIndex);
-    }
-    //
-    //
-    //
-    private int getHashcode(int offset, int length) {
-        int endOffset = offset + length;
-        int hashcode = 0;
-        while (offset < endOffset) {
-            int ch;
-            try {
-                ch = getChar(offset);
-            }
-            catch (IOException ex) {
-                ch = 0; // REVISIT
-            }
-            hashcode = StringHasher.hashChar(hashcode, ch);
-            offset += fBytesPerChar;
-        }
-        return StringHasher.finishHash(hashcode);
-    }
-    //
-    public boolean equalsString(int offset, int length, char[] strChars, int strOffset, int strLength) {
-        int endOffset = offset + length;
-        int slen = strLength;
-        while (offset < endOffset) {
-            if (slen-- == 0)
-                return false;
-            int ch;
-            try {
-                ch = getChar(offset);
-            }
-            catch (IOException ex) {
-                ch = 0; // REVISIT
-            }
-            if (ch != strChars[strOffset++])
-                return false;
-            offset += fBytesPerChar;
-        }
-        return slen == 0;
-    }
-    //
-    //
-    //
-    private static char[] fCharacters = new char[256];
-    private int fCharDataLength = 0;
-    private void appendCharData(int ch) {
-        if (fCharacters.length == fCharDataLength) {
-            char[] newchars = new char[fCharacters.length * 2];
-            System.arraycopy(fCharacters, 0, newchars, 0, fCharacters.length);
-            fCharacters = newchars;
-        }
-        fCharacters[fCharDataLength++] = (char)ch;
-    }
-    public void callCharDataHandler(int offset, int length, boolean isWhitespace) throws Exception {
-        int endOffset = offset + length;
-        boolean skiplf = false;
-        while (offset < endOffset) {
-            int ch = getChar(offset);
-            // fix for Bug23: Element Data not normalized...
-            if (skiplf) {
-                skiplf = false;
-                if (ch == 0x0A) {
-                    offset += fBytesPerChar;
-                    continue;
-                }
-            }
-            if (ch == 0x0D) {
-                skiplf = true;
-                ch = 0x0A;
-            }
-            appendCharData(ch);
-            offset += fBytesPerChar;
-        }
-        if (fSendCharDataAsCharArray) {
-            if (isWhitespace)
-                fCharDataHandler.processWhitespace(fCharacters, 0, fCharDataLength);
-            else
-                fCharDataHandler.processCharacters(fCharacters, 0, fCharDataLength);
-        } else {
-            int stringIndex = fStringPool.addString(new String(fCharacters, 0, fCharDataLength));
-            if (isWhitespace)
-                fCharDataHandler.processWhitespace(stringIndex);
-            else
-                fCharDataHandler.processCharacters(stringIndex);
-        }
-        fCharDataLength = 0;
-    }
-    //
-    //
-    //
-    public boolean lookingAtChar(char ch, boolean skipPastChar) throws Exception {
-        int ch2 = getChar(fCurrentOffset);
-        if (ch2 == ch) {
-            if (skipPastChar) {
-                fCharacterCounter++;
-                fCurrentOffset += fBytesPerChar;
-            }
-            return true;
-        }
-        return false;
-    }
-    //
-    //
-    //
-    public boolean lookingAtValidChar(boolean skipPastChar) throws Exception {
-        int ch = getChar(fCurrentOffset);
-        if (ch < 0x20) {
-            if (ch == 0x09) {
-                if (!skipPastChar)
-                    return true;
-                fCharacterCounter++;
-            } else if (ch == 0x0A) {
-                if (!skipPastChar)
-                    return true;
-                fLinefeedCounter++;
-                fCharacterCounter = 1;
-            } else if (ch == 0x0D) {
-                if (!skipPastChar)
-                    return true;
-                fCarriageReturnCounter++;
-                fCharacterCounter = 1;
-            } else {
-                if (ch == -1) {
-                    return changeReaders().lookingAtValidChar(skipPastChar);
-                }
-                return false;
-            }
-            fCurrentOffset += fBytesPerChar;
-            return true;
-        }
-        if (ch <= 0xD7FF) {
-            if (skipPastChar) {
-                fCharacterCounter++;
-                fCurrentOffset += fBytesPerChar;
-            }
-            return true;
-        }
-        if (ch <= 0xDFFF) {
-            // REVISIT - check that the surrogate pair is valid
-            if (skipPastChar) {
-                fCharacterCounter++;
-                fCurrentOffset += fBytesPerChar;
-            }
-            return true;
-        }
-        if (ch <= 0xFFFD) {
-            if (skipPastChar) {
-                fCharacterCounter++;
-                fCurrentOffset += fBytesPerChar;
-            }
-            return true;
-        }
-        return false;
-    }
-    //
-    //
-    //
-    public boolean lookingAtSpace(boolean skipPastChar) throws Exception {
-        int ch = getChar(fCurrentOffset);
-        if (ch > 0x20)
-            return false;
-        if (ch == 0x20 || ch == 0x09) {
-            if (!skipPastChar)
-                return true;
-            fCharacterCounter++;
-        } else if (ch == 0x0A) {
-            if (!skipPastChar)
-                return true;
-            fLinefeedCounter++;
-            fCharacterCounter = 1;
-        } else if (ch == 0x0D) {
-            if (!skipPastChar)
-                return true;
-            fCarriageReturnCounter++;
-            fCharacterCounter = 1;
-        } else {
-            if (ch == -1) { // REVISIT - should we be checking this here ?
-                return changeReaders().lookingAtSpace(skipPastChar);
-            }
-            return false;
-        }
-        fCurrentOffset += fBytesPerChar;
-        return true;
-    }
-    //
-    //
-    //
-    public void skipToChar(char chr) throws Exception {
-        while (true) {
-            int ch = getChar(fCurrentOffset);
-            if (ch == chr)
-                return;
-            if (ch == -1) {
-                changeReaders().skipToChar(chr);
-                return;
-            }
-            if (ch == 0x0A) {
-                fLinefeedCounter++;
-                fCharacterCounter = 1;
-            } else if (ch == 0x0D) {
-                fCarriageReturnCounter++;
-                fCharacterCounter = 1;
-            } else if (ch >= 0xD800 && ch < 0xDC00) {
-                fCharacterCounter++;
-                fCurrentOffset += fBytesPerChar;
-                ch = getChar(fCurrentOffset);
-                if (ch < 0xDC00 || ch >= 0xE000)
-                    continue;
-            } else
-                fCharacterCounter++;
-            fCurrentOffset += fBytesPerChar;
-        }
-    }
-    //
-    //
-    //
-    public void skipPastSpaces() throws Exception {
-        while (true) {
-            int ch = getChar(fCurrentOffset);
-            if (ch > 0x20)
-                return;
-            if (ch == 0x20 || ch == 0x09) {
-                fCharacterCounter++;
-            } else if (ch == 0x0A) {
-                fLinefeedCounter++;
-                fCharacterCounter = 1;
-            } else if (ch == 0x0D) {
-                fCarriageReturnCounter++;
-                fCharacterCounter = 1;
-            } else {
-                if (ch == -1)
-                    changeReaders().skipPastSpaces();
-                return;
-            }
-            fCurrentOffset += fBytesPerChar;
-        }
-    }
-    //
-    //
-    //
-    public void skipPastName(char fastcheck) throws Exception {
-        int ch = getChar(fCurrentOffset);
-        if (!fCalledCharPropInit) {
-            XMLCharacterProperties.initCharFlags();
-            fCalledCharPropInit = true;
-        }
-        if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
-            return;
-        while (true) {
-            fCurrentOffset += fBytesPerChar;
-            fCharacterCounter++;
-            ch = getChar(fCurrentOffset);
-            if (fastcheck == ch)
-                return;
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                return;
-        }
-    }
-    //
-    //
-    //
-    public void skipPastNmtoken(char fastcheck) throws Exception {
-        int ch = getChar(fCurrentOffset);
-        if (!fCalledCharPropInit) {
-            XMLCharacterProperties.initCharFlags();
-            fCalledCharPropInit = true;
-        }
-        while (true) {
-            if (fastcheck == ch)
-                return;
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                return;
-            fCurrentOffset += fBytesPerChar;
-            fCharacterCounter++;
-            ch = getChar(fCurrentOffset);
-        }
-    }
-    //
-    //
-    //
-    public boolean skippedString(char[] s) throws Exception {
-        int offset = fCurrentOffset;
-        for (int i = 0; i < s.length; i++) {
-            if (getChar(offset) != s[i])
-                return false;
-            offset += fBytesPerChar;
-        }
-        fCurrentOffset = offset;
-        fCharacterCounter += s.length;
-        return true;
-    }
-    //
-    //
-    //
-    public int scanInvalidChar() throws Exception {
-        int ch = getChar(fCurrentOffset);
-        if (ch == -1) {
-            return changeReaders().scanInvalidChar();
-        }
-        fCurrentOffset += fBytesPerChar;
-        if (ch == 0x0A) {
-            fLinefeedCounter++;
-            fCharacterCounter = 1;
-        } else if (ch == 0x0D) {
-            fCarriageReturnCounter++;
-            fCharacterCounter = 1;
-        } else {
-            fCharacterCounter++;
-            if (ch >= 0xD800 && ch < 0xDC00) {
-                int ch2 = getChar(fCurrentOffset);
-                if (ch2 >= 0xDC00 && ch2 < 0xE000) {
-                    ch = ((ch-0xD800)<<10)+(ch2-0xDC00)+0x10000;
-                    fCurrentOffset += fBytesPerChar;
-                }
-            }
-        }
-        return ch;
-    }
-    //
-    //
-    //
-    public int scanCharRef(boolean hex) throws Exception {
-        int ch = getChar(fCurrentOffset);
-        if (ch == -1) {
-            return changeReaders().scanCharRef(hex);
-        }
-        int num = 0;
-        if (hex) {
-            if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
-                return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-            num = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
-        } else {
-            if (ch < '0' || ch > '9')
-                return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-            num = ch - '0';
-        }
-        fCharacterCounter++;
-        fCurrentOffset += fBytesPerChar;
-        boolean toobig = false;
-        while (true) {
-            ch = getChar(fCurrentOffset);
-            if (ch == -1)
-                break;
-            if (hex) {
-                if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
-                    break;
-            } else {
-                if (ch < '0' || ch > '9')
-                    break;
-            }
-            fCharacterCounter++;
-            fCurrentOffset += fBytesPerChar;
-            if (hex) {
-                int dig = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
-                num = (num << 4) + dig;
-            } else {
-                int dig = ch - '0';
-                num = (num * 10) + dig;
-            }
-            if (num > 0x10FFFF) {
-                toobig = true;
-                num = 0;
-            }
-        }
-        if (ch != ';')
-            return XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED;
-        fCharacterCounter++;
-        fCurrentOffset += fBytesPerChar;
-        if (toobig)
-            return XMLEntityHandler.CHARREF_RESULT_OUT_OF_RANGE;
-        return num;
-    }
-    //
-    //
-    //
-    public int scanStringLiteral() throws Exception {
-        boolean single;
-        if (!(single = lookingAtChar('\'', true)) && !lookingAtChar('\"', true)) {
-            return XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED;
-        }
-        int offset = fCurrentOffset;
-        char qchar = single ? '\'' : '\"';
-        while (!lookingAtChar(qchar, false)) {
-            if (!lookingAtValidChar(true)) {
-                return XMLEntityHandler.STRINGLIT_RESULT_INVALID_CHAR;
-            }
-        }
-        int stringIndex = addString(offset, fCurrentOffset - offset);
-        lookingAtChar(qchar, true); // move past qchar
-        return stringIndex;
-    }
-    //
-    // [10] AttValue ::= '"' ([^<&"] | Reference)* '"'
-    //                   | "'" ([^<&'] | Reference)* "'"
-    //
-    public int scanAttValue(char qchar, boolean asSymbol) throws Exception
-    {
-        int offset = fCurrentOffset;
-        while (true) {
-            if (lookingAtChar(qchar, false)) {
-                break;
-            }
-            if (lookingAtChar(' ', true)) {
-                continue;
-            }
-            if (lookingAtSpace(false)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_COMPLEX;
-            }
-            if (lookingAtChar('&', false)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_COMPLEX;
-            }
-            if (lookingAtChar('<', false)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_LESSTHAN;
-            }
-            if (!lookingAtValidChar(true)) {
-                return XMLEntityHandler.ATTVALUE_RESULT_INVALID_CHAR;
-            }
-        }
-        int result = asSymbol ? addSymbol(offset, fCurrentOffset - offset) : addString(offset, fCurrentOffset - offset);
-        lookingAtChar(qchar, true);
-        return result;
-    }
-    //
-    //  [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
-    //                      | "'" ([^%&'] | PEReference | Reference)* "'"
-    //
-    public int scanEntityValue(int qchar, boolean createString) throws Exception
-    {
-        int offset = fCurrentOffset;
-        while (true) {
-            if (qchar != -1 && lookingAtChar((char)qchar, false)) {
-                if (!createString)
-                    return XMLEntityHandler.ENTITYVALUE_RESULT_FINISHED;
-                break;
-            }
-            if (lookingAtChar('&', false)) {
-                return XMLEntityHandler.ENTITYVALUE_RESULT_REFERENCE;
-            }
-            if (lookingAtChar('%', false)) {
-                return XMLEntityHandler.ENTITYVALUE_RESULT_PEREF;
-            }
-            if (!lookingAtValidChar(true)) {
-                return XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR;
-            }
-        }
-        int result = addString(offset, fCurrentOffset - offset);
-        lookingAtChar((char)qchar, true);
-        return result;
-    }
-    //
-    //
-    //
-    public boolean scanExpectedName(char fastcheck, StringPool.CharArrayRange expectedName) throws Exception {
-        int nameOffset = fCurrentOffset;
-        skipPastName(fastcheck);
-        int nameLength = fCurrentOffset - nameOffset;
-        if (nameLength == 0)
-            return false;
-        int nameIndex = addSymbol(nameOffset, nameLength);
-        // DEFECT !! check name against expected name
-        return true;
-    }
-
-    public void scanQName(char fastcheck, QName qname) throws Exception {
-
-        // DEFECT !! no code // Defect #126
-        int nameOffset = fCurrentOffset;
-        skipPastName(fastcheck);
-        int nameLength = fCurrentOffset - nameOffset;
-        if (nameLength == 0) {
-            qname.clear();
-            return;
-        }
-        qname.prefix = -1;
-        qname.localpart = -1;
-        qname.rawname = addSymbol(nameOffset, nameLength);
-        qname.uri = -1;
-
-    } // scanQName(char,QName)
-
-    public int scanName(char fastcheck) throws Exception {
-        int nameOffset = fCurrentOffset;
-        skipPastName(fastcheck);
-        int nameLength = fCurrentOffset - nameOffset;
-        if (nameLength == 0)
-            return -1;
-        int nameIndex = addSymbol(nameOffset, nameLength);
-        return nameIndex;
-    }
-    //
-    //
-    //
-    private static final char[] cdata_string = { 'C','D','A','T','A','[' };
-    private int recognizeMarkup() throws Exception {
-        int ch = getChar(fCurrentOffset);
-        switch (ch) {
-        case -1:
-            return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-        case '?':
-            fCharacterCounter++;
-            fCurrentOffset += fBytesPerChar;
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_PI;
-        case '!':
-            fCharacterCounter++;
-            fCurrentOffset += fBytesPerChar;
-            ch = getChar(fCurrentOffset);
-            if (ch == -1) {
-                fCharacterCounter--;
-                fCurrentOffset -= fBytesPerChar;;
-                return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-            }
-            if (ch == '-') {
-                fCharacterCounter++;
-                fCurrentOffset += fBytesPerChar;
-                ch = getChar(fCurrentOffset);
-                if (ch == -1) {
-                    fCharacterCounter -= 2;
-                    fCurrentOffset -= 2;
-                    return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-                }
-                if (ch == '-') {
-                    fCharacterCounter++;
-                    fCurrentOffset += fBytesPerChar;
-                    return XMLEntityHandler.CONTENT_RESULT_START_OF_COMMENT;
-                }
-                break;
-            }
-            if (ch == '[') {
-                fCharacterCounter++;
-                fCurrentOffset += fBytesPerChar;
-                for (int i = 0; i < 6; i++) {
-                    ch = getChar(fCurrentOffset);
-                    if (ch == -1) {
-                        fCharacterCounter -= (2 + i);
-                        fCurrentOffset -= ((2 + i) * fBytesPerChar);
-                        return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-                    }
-                    if (ch != cdata_string[i]) {
-                        return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
-                    }
-                    fCharacterCounter++;
-                    fCurrentOffset += fBytesPerChar;
-                }
-                return XMLEntityHandler.CONTENT_RESULT_START_OF_CDSECT;
-            }
-            break;
-        case '/':
-            fCharacterCounter++;
-            fCurrentOffset += fBytesPerChar;
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ETAG;
-        default:
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ELEMENT;
-        }
-        return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
-    }
-    private int recognizeReference() throws Exception {
-        int ch = getChar(fCurrentOffset);
-        if (ch == -1) {
-            return XMLEntityHandler.CONTENT_RESULT_REFERENCE_END_OF_INPUT;
-        }
-        //
-        // [67] Reference ::= EntityRef | CharRef
-        // [68] EntityRef ::= '&' Name ';'
-        // [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
-        //
-        if (ch == '#') {
-            fCharacterCounter++;
-            fCurrentOffset += fBytesPerChar;
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_CHARREF;
-        } else {
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ENTITYREF;
-        }
-    }
-    public int scanContent(QName element) throws Exception {
-        int offset = fCurrentOffset;
-        int ch = getChar(fCurrentOffset);
-        fCurrentOffset += fBytesPerChar;
-        byte prop;
-        if (!fCalledCharPropInit) {
-            XMLCharacterProperties.initCharFlags();
-            fCalledCharPropInit = true;
-        }
-        if (ch < 0x80) {
-            if (ch == -1) {
-                fCurrentOffset -= fBytesPerChar;
-                return changeReaders().scanContent(element); // REVISIT - not quite...
-            }
-            prop = XMLCharacterProperties.fgCharFlags[ch];
-            if ((prop & XMLCharacterProperties.E_CharDataFlag) == 0 && ch != 0x0A && ch != 0x0D) {
-                if (ch == '<') {
-                    fCharacterCounter++;
-                    if (!fInCDSect) {
-                        return recognizeMarkup();
-                    }
-                } else if (ch == '&') {
-                    fCharacterCounter++;
-                    if (!fInCDSect) {
-                        return recognizeReference();
-                    }
-                } else if (ch == ']') {
-                    if (getChar(fCurrentOffset) == ']' && getChar(fCurrentOffset + fBytesPerChar) == '>') {
-                        fCharacterCounter += 3;
-                        fCurrentOffset += (2 * fBytesPerChar);
-                        return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-                    }
-                } else {
-                    fCurrentOffset -= fBytesPerChar;
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-            } else if (ch == 0x20 || ch == 0x09 || ch == 0x0A || ch == 0x0D) {
-                do {
-                    if (ch == 0x0A) {
-                        fLinefeedCounter++;
-                        fCharacterCounter = 1;
-                    } else if (ch == 0x0D) {
-                        fCarriageReturnCounter++;
-                        fCharacterCounter = 1;
-                    } else {
-                        fCharacterCounter++;
-                    }
-                    ch = getChar(fCurrentOffset);
-                    fCurrentOffset += fBytesPerChar;
-                } while (ch == 0x20 || ch == 0x09 || ch == 0x0A || ch == 0x0D);
-                if (ch < 0x80) {
-                    if (ch == -1) {
-                        fCurrentOffset -= fBytesPerChar;
-                        callCharDataHandler(offset, fCurrentOffset - offset, true);
-                        return changeReaders().scanContent(element); // REVISIT - not quite...
-                    }
-                    prop = XMLCharacterProperties.fgCharFlags[ch];
-                    if ((prop & XMLCharacterProperties.E_CharDataFlag) == 0) {
-                        if (ch == '<') {
-                            if (!fInCDSect) {
-                                callCharDataHandler(offset, (fCurrentOffset - fBytesPerChar) - offset, true);
-                                fCharacterCounter++;
-                                return recognizeMarkup();
-                            }
-                            fCharacterCounter++;
-                        } else if (ch == '&') {
-                            if (!fInCDSect) {
-                                callCharDataHandler(offset, (fCurrentOffset - fBytesPerChar) - offset, true);
-                                fCharacterCounter++;
-                                return recognizeReference();
-                            }
-                            fCharacterCounter++;
-                        } else if (ch == ']') {
-                            if (getChar(fCurrentOffset) == ']' && getChar(fCurrentOffset + fBytesPerChar) == '>') {
-                                callCharDataHandler(offset, (fCurrentOffset - fBytesPerChar) - offset, true);
-                                fCharacterCounter += 3;
-                                fCurrentOffset += (2 * fBytesPerChar);
-                                return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-                            }
-                        } else {
-                            fCurrentOffset -= fBytesPerChar;
-                            callCharDataHandler(offset, fCurrentOffset - offset, true);
-                            return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                        }
-                    }
-                } else {
-                    if (ch >= 0xD800 && ch <= 0xDFFF) {
-                        fCurrentOffset += fBytesPerChar;
-                    } else if (ch == 0xFFFE || ch == 0xFFFF) {
-                        fCurrentOffset -= fBytesPerChar;
-                        callCharDataHandler(offset, fCurrentOffset - offset, true);
-                        return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                    }
-                }
-            }
-        } else {
-            if (ch >= 0xD800 && ch <= 0xDFFF) {
-                fCurrentOffset += fBytesPerChar;
-            } else if (ch == 0xFFFE || ch == 0xFFFF) {
-                fCurrentOffset -= fBytesPerChar;
-                return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-            }
-        }
-        fCharacterCounter++;
-        while (true) {
-            ch = getChar(fCurrentOffset);
-            fCurrentOffset += fBytesPerChar;
-            if (ch >= 0x80 || ch < 0)
-                break;
-            prop = XMLCharacterProperties.fgCharFlags[ch];
-            if ((prop & XMLCharacterProperties.E_CharDataFlag) == 0) {
-                if (ch == 0x0A) {
-                    fLinefeedCounter++;
-                    fCharacterCounter = 1;
-                } else if (ch == 0x0D) {
-                    fCarriageReturnCounter++;
-                    fCharacterCounter = 1;
-                } else
-                    break;
-            } else
-                fCharacterCounter++;
-        }
-        while (true) { // REVISIT - EOF check ?
-            if (ch < 0x80) {
-                if (ch == -1) {
-                    fCurrentOffset -= fBytesPerChar;
-                    callCharDataHandler(offset, fCurrentOffset - offset, false);
-                    return changeReaders().scanContent(element); // REVISIT - not quite...
-                }
-                prop = XMLCharacterProperties.fgCharFlags[ch];
-                if ((prop & XMLCharacterProperties.E_CharDataFlag) == 0) {
-                    if (ch == '<') {
-                        if (!fInCDSect) {
-                            callCharDataHandler(offset, (fCurrentOffset - fBytesPerChar) - offset, false);
-                            fCharacterCounter++;
-                            return recognizeMarkup();
-                        }
-                        fCharacterCounter++;
-                    } else if (ch == '&') {
-                        if (!fInCDSect) {
-                            callCharDataHandler(offset, (fCurrentOffset - fBytesPerChar) - offset, false);
-                            fCharacterCounter++;
-                            return recognizeReference();
-                        }
-                        fCharacterCounter++;
-                    } else if (ch == 0x0A) {
-                        fLinefeedCounter++;
-                        fCharacterCounter = 1;
-                    } else if (ch == 0x0D) {
-                        fCarriageReturnCounter++;
-                        fCharacterCounter = 1;
-                    } else if (ch == ']') {
-                        if (getChar(fCurrentOffset) == ']' && getChar(fCurrentOffset + fBytesPerChar) == '>') {
-                            callCharDataHandler(offset, (fCurrentOffset - fBytesPerChar) - offset, false);
-                            fCharacterCounter += 3;
-                            fCurrentOffset += (2 * fBytesPerChar);
-                            return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-                        }
-                        fCharacterCounter++;
-                    } else {
-                        fCurrentOffset -= fBytesPerChar;
-                        callCharDataHandler(offset, fCurrentOffset - offset, false);
-                        return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                    }
-                } else {
-                    fCharacterCounter++;
-                }
-            } else {
-                if (ch >= 0xD800 && ch <= 0xDFFF) {
-                    fCharacterCounter++;
-                    fCurrentOffset += fBytesPerChar;
-                } else if (ch == 0xFFFE || ch == 0xFFFF) {
-                    fCurrentOffset -= fBytesPerChar;
-                    callCharDataHandler(offset, fCurrentOffset - offset, false);
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-                fCharacterCounter++;
-            }
-            ch = getChar(fCurrentOffset);
-            fCurrentOffset += fBytesPerChar;
-        }
-    }
-}
diff --git a/src/org/apache/xerces/readers/UCSRecognizer.java b/src/org/apache/xerces/readers/UCSRecognizer.java
deleted file mode 100644
index e40eddb..0000000
--- a/src/org/apache/xerces/readers/UCSRecognizer.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.ChunkyByteArray;
-import org.apache.xerces.utils.StringPool;
-
-import java.io.IOException;
-
-/**
- *
- * @version
- */
-final class UCSRecognizer extends XMLDeclRecognizer {
-    //
-    //
-    //
-    public XMLEntityHandler.EntityReader recognize(XMLEntityReaderFactory readerFactory,
-                                                   XMLEntityHandler entityHandler,
-                                                   XMLErrorReporter errorReporter,
-                                                   boolean sendCharDataAsCharArray,
-                                                   StringPool stringPool,
-                                                   ChunkyByteArray data,
-                                                   boolean xmlDecl,
-                                                   boolean allowJavaEncodingName) throws Exception
-    {
-        XMLEntityHandler.EntityReader reader = null;
-        byte b0 = data.byteAt(0);
-        if (b0 == 0) {
-            int b1 = data.byteAt(1);
-            if (b1 == 0) {
-                if (data.byteAt(2) == 0 && data.byteAt(3) == '<')
-                    reader = new UCSReader(entityHandler, errorReporter, sendCharDataAsCharArray, data, UCSReader.E_UCS4B, stringPool);
-            } else if (b1 == '<') {
-                if (data.byteAt(2) == 0 && data.byteAt(3) == '?')
-                    reader = new UCSReader(entityHandler, errorReporter, sendCharDataAsCharArray, data, UCSReader.E_UCS2B_NOBOM, stringPool);
-            }
-        } else if (b0 == '<') {
-            int b1 = data.byteAt(1);
-            if (b1 == 0) {
-                int b2 = data.byteAt(2);
-                if (data.byteAt(3) == 0) {
-                    if (b2 == 0)
-                        reader = new UCSReader(entityHandler, errorReporter, sendCharDataAsCharArray, data, UCSReader.E_UCS4L, stringPool);
-                    else if (b2 == '?')
-                        reader = new UCSReader(entityHandler, errorReporter, sendCharDataAsCharArray, data, UCSReader.E_UCS2L_NOBOM, stringPool);
-                }
-            }
-        } else if (b0 == (byte)0xfe) {
-            if (data.byteAt(1) == (byte)0xff)
-                reader = new UCSReader(entityHandler, errorReporter, sendCharDataAsCharArray, data, UCSReader.E_UCS2B, stringPool);
-        } else if (b0 == (byte)0xff) {
-            if (data.byteAt(1) == (byte)0xfe)
-                reader = new UCSReader(entityHandler, errorReporter, sendCharDataAsCharArray, data, UCSReader.E_UCS2L, stringPool);
-        }
-        return reader;
-    }
-}
diff --git a/src/org/apache/xerces/readers/UTF8CharReader.java b/src/org/apache/xerces/readers/UTF8CharReader.java
deleted file mode 100644
index 6289824..0000000
--- a/src/org/apache/xerces/readers/UTF8CharReader.java
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.CharDataChunk;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.utils.ImplementationMessages;
-import java.io.InputStream;
-
-/**
- * Simple character-based version of a UTF8 reader.
- *
- * This class is not commonly used, but is provided as a much simplified
- * example of the UTF8Reader class that uses the AbstractCharReader to
- * perform all of the reader functions except for filling each buffer
- * of the character data when needed (fillCurrentChunk).  We read the
- * input data from an InputStream and perform end-of-line normalization
- * as we process that data.
- *
- * @version
- */
-final class UTF8CharReader extends AbstractCharReader {
-    //
-    //
-    //
-    UTF8CharReader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter, boolean sendCharDataAsCharArray, InputStream dataStream, StringPool stringPool) throws Exception {
-        super(entityHandler, errorReporter, sendCharDataAsCharArray, stringPool);
-        fInputStream = dataStream;
-        fillCurrentChunk();
-    }
-    //
-    //
-    //
-    private InputStream fInputStream = null;
-    //
-    // When we fill a chunk there may be data that was read from the
-    // input stream that has not been "processed".  We need to save
-    // that data, and any in-progress state, between the calls to
-    // fillCurrentChunk() in these instance variables.  
-    //
-    private boolean fCheckOverflow = false;
-    private byte[] fOverflow = null;
-    private int fOverflowOffset = 0;
-    private int fOverflowEnd = 0;
-    private int fOutputOffset = 0;
-    private boolean fSkipLinefeed = false;
-    private int fPartialMultiByteIn = 0;
-    private byte[] fPartialMultiByteChar = new byte[3];
-    private int fPartialSurrogatePair = 0;
-    private boolean fPartialMultiByteResult = false;
-    //
-    //
-    //
-    protected int fillCurrentChunk() throws Exception {
-        //
-        // See if we can find a way to reuse the buffer that may have been returned
-        // with a recyled data chunk.
-        //
-        char[] recycledData = fCurrentChunk.toCharArray();
-        //
-        // If we have overflow from the last call, normalize from where
-        // we left off, copying into the front of the output buffer.
-        //
-        fOutputOffset = 0;
-        if (fCheckOverflow) {
-            //
-            // The fOverflowEnd should always be equal to CHUNK_SIZE, unless we hit
-            // EOF during the previous call.  Copy the remaining data to the front
-            // of the buffer and return it as the final chunk.
-            //
-            fMostRecentData = recycledData;
-            if (fOverflowEnd < CharDataChunk.CHUNK_SIZE) {
-                recycledData = null;
-                if (fOverflowEnd > 0) {
-                    if (fMostRecentData == null || fMostRecentData.length < 1 + fOverflowEnd - fOverflowOffset)
-                        fMostRecentData = new char[1 + fOverflowEnd - fOverflowOffset];
-                    copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset);
-                } else {
-                    if (fMostRecentData == null)
-                        fMostRecentData = new char[1];
-                }
-                fMostRecentData[fOutputOffset] = 0;
-                //
-                // Update our instance variables
-                //
-                fOverflow = null;
-                fLength += fOutputOffset;
-                fCurrentIndex = 0;
-                fCurrentChunk.setCharArray(fMostRecentData);
-                return (fMostRecentChar = fMostRecentData[0]);
-            }
-            if (fMostRecentData == null || fMostRecentData.length < CharDataChunk.CHUNK_SIZE)
-                fMostRecentData = new char[CharDataChunk.CHUNK_SIZE];
-            else
-                recycledData = null;
-            copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset);
-            fCheckOverflow = false;
-        } else {
-            if (fOverflow == null)
-                fOverflow = new byte[CharDataChunk.CHUNK_SIZE];
-            fMostRecentData = null;
-        }
-        while (true) {
-            fOverflowOffset = 0;
-            fOverflowEnd = 0;
-            int capacity = CharDataChunk.CHUNK_SIZE;
-            int result = 0;
-            do {
-                try {
-                    result = fInputStream.read(fOverflow, fOverflowEnd, capacity);
-                } catch (java.io.IOException ex) {
-                    result = -1;
-                }
-                if (result == -1) {
-                    //
-                    // We have reached the end of the stream.
-                    //
-                    fInputStream.close();
-                    fInputStream = null;
-                    if (fMostRecentData == null) {
-                        //
-                        // There is no previous output data, so we know that all of the
-                        // new input data will fit.
-                        //
-                        fMostRecentData = recycledData;
-                        if (fMostRecentData == null || fMostRecentData.length < 1 + fOverflowEnd)
-                            fMostRecentData = new char[1 + fOverflowEnd];
-                        else
-                            recycledData = null;
-                        copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset);
-                        fOverflow = null;
-                        fMostRecentData[fOutputOffset] = 0;
-                    } else {
-                        //
-                        // Copy the input data to the end of the output buffer.
-                        //
-                        boolean alldone = copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset);
-                        if (alldone) {
-                            if (fOverflowEnd == CharDataChunk.CHUNK_SIZE) {
-                                //
-                                // Special case - everything fit into the overflow buffer,
-                                // except that there is no room for the nul char we use to
-                                // indicate EOF.  Set the overflow buffer length to zero.
-                                // On the next call to this method, we will detect this
-                                // case and which we will handle above .
-                                //
-                                fCheckOverflow = true;
-                                fOverflowOffset = 0;
-                                fOverflowEnd = 0;
-                            } else {
-                                //
-                                // It all fit into the output buffer.
-                                //
-                                fOverflow = null;
-                                fMostRecentData[fOutputOffset] = 0;
-                            }
-                        } else {
-                            //
-                            // There is still input data left over, save the remaining data as
-                            // the overflow buffer for the next call.
-                            //
-                            fCheckOverflow = true;
-                        }
-                    }
-                    break;
-                }
-                if (result > 0) {
-                    fOverflowEnd += result;
-                    capacity -= result;
-                }
-            } while (capacity > 0);
-            //
-            //
-            //
-            if (result == -1)
-                break;
-            if (fMostRecentData != null) {
-                boolean alldone = copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset);
-                if (fOutputOffset == CharDataChunk.CHUNK_SIZE) {
-                    //
-                    // We filled the output buffer.
-                    //
-                    if (!alldone) {
-                        //
-                        // The input buffer will become the next overflow buffer.
-                        //
-                        fCheckOverflow = true;
-                    }
-                    break;
-                }
-            } else {
-                //
-                // Now normalize the end-of-line characters and see if we need to read more
-                // bytes to fill up the buffer.
-                //
-                fMostRecentData = recycledData;
-                if (fMostRecentData == null || fMostRecentData.length < CharDataChunk.CHUNK_SIZE)
-                    fMostRecentData = new char[CharDataChunk.CHUNK_SIZE];
-                else
-                    recycledData = null;
-                copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset);
-                if (fOutputOffset == CharDataChunk.CHUNK_SIZE) {
-                    //
-                    // The output buffer is full.  We can return now.
-                    //
-                    break;
-                }
-            }
-            //
-            // We will need to get another intput buffer to be able to fill the
-            // overflow buffer completely.
-            //
-        }
-        //
-        // Update our instance variables
-        //
-        fLength += fOutputOffset;
-        fCurrentIndex = 0;
-        fCurrentChunk.setCharArray(fMostRecentData);
-        return (fMostRecentChar = fMostRecentData[0]);
-    }
-    //
-    // Copy and normalize bytes from the overflow buffer into chars in our data buffer.
-    //
-    private boolean copyNormalize(byte[] in, int inOffset, char[] out, int outOffset) throws Exception {
-        //
-        // Handle all edge cases before dropping into the inner loop.
-        //
-        int inEnd = fOverflowEnd;
-        int outEnd = out.length;
-        if (inOffset == inEnd)
-            return true;
-        byte b = in[inOffset];
-        if (fSkipLinefeed) {
-            fSkipLinefeed = false;
-            if (b == 0x0A) {
-                if (++inOffset == inEnd)
-                    return exitNormalize(inOffset, outOffset, true);
-                b = in[inOffset];
-            }
-        } else if (fPartialMultiByteIn > 0) {
-            if (!handlePartialMultiByteChar(b, in, inOffset, inEnd, out, outOffset, outEnd))
-                return fPartialMultiByteResult;
-            inOffset = fOverflowOffset;
-            outOffset = fOutputOffset;
-            b = in[inOffset];
-        }
-        while (outOffset < outEnd) {
-            //
-            // Find the longest run that we can guarantee will not exceed the
-            // bounds of the outer loop.
-            //
-            int inCount = inEnd - inOffset;
-            int outCount = outEnd - outOffset;
-            if (inCount > outCount)
-                inCount = outCount;
-            inOffset++;
-            while (true) {
-                while (b == 0x0D || b < 0) {
-                    if (b == 0x0D) {
-                        out[outOffset++] = 0x0A;
-                        if (inOffset == inEnd) {
-                            fSkipLinefeed = true;
-                            return exitNormalize(inOffset, outOffset, true);
-                        }
-                        b = in[inOffset];
-                        if (b == 0x0A) {
-                            if (++inOffset == inEnd)
-                                return exitNormalize(inOffset, outOffset, true);
-                            b = in[inOffset];
-                        }
-                        if (outOffset == outEnd)
-                            return exitNormalize(inOffset, outOffset, false);
-                    } else {
-                        if (!handleMultiByteChar(b, in, inOffset, inEnd, out, outOffset, outEnd))
-                            return fPartialMultiByteResult;
-                        inOffset = fOverflowOffset;
-                        outOffset = fOutputOffset;
-                        b = in[inOffset];
-                    }
-                    inCount = inEnd - inOffset;
-                    outCount = outEnd - outOffset;
-                    if (inCount > outCount)
-                        inCount = outCount;
-                    inOffset++;
-                }
-                while (true) {
-                    out[outOffset++] = (char)b;
-                    if (--inCount == 0)
-                        break;
-                    b = in[inOffset++];
-                    if (b == 0x0D || b < 0)
-                        break;
-                }
-                if (inCount == 0)
-                    break;
-            }
-            if (inOffset == inEnd)
-                break;
-        }
-        return exitNormalize(inOffset, outOffset, inOffset == inEnd);
-    }
-    //
-    //
-    //
-    private boolean exitNormalize(int inOffset, int outOffset, boolean result) {
-        fOverflowOffset = inOffset;
-        fOutputOffset = outOffset;
-        return result;
-    }
-    //
-    //
-    //
-    private void savePartialMultiByte(int inCount, byte bz, byte by, byte bx) {
-        fPartialMultiByteIn = inCount;
-        fPartialMultiByteChar[--inCount] = bz;
-        fPartialMultiByteChar[--inCount] = by;
-        fPartialMultiByteChar[--inCount] = bx;
-    }
-    private void savePartialMultiByte(int inCount, byte bz, byte by) {
-        fPartialMultiByteIn = inCount;
-        fPartialMultiByteChar[--inCount] = bz;
-        fPartialMultiByteChar[--inCount] = by;
-    }
-    private void savePartialMultiByte(int inCount, byte bz) {
-        fPartialMultiByteIn = inCount;
-        fPartialMultiByteChar[--inCount] = bz;
-    }
-    private boolean handleMultiByteChar(byte b, byte[] in, int inOffset, int inEnd, char[] out, int outOffset, int outEnd) throws Exception {
-        if (inOffset == inEnd) {
-            savePartialMultiByte(1, b);
-            fPartialMultiByteResult = exitNormalize(inOffset, outOffset, true);
-            return false;
-        }
-        byte b1 = in[inOffset++];
-        if ((b1 & 0xc0) != 0x80) {
-            Object[] args = {
-                Integer.toHexString(b & 0xff),
-                Integer.toHexString(b1 & 0xff)
-            };
-            deferException(ImplementationMessages.ENC5, args, outOffset);
-            out[outOffset++] = 0;
-            return exitNormalize(inOffset, outOffset, true);
-        }
-        if ((b & 0xe0) == 0xc0) { // 110yyyyy 10xxxxxx
-            int ch = ((0x1f & b)<<6) + (0x3f & b1);
-            out[outOffset++] = (char)ch;
-            if (inOffset == inEnd || outOffset == outEnd) {
-                fPartialMultiByteResult = exitNormalize(inOffset, outOffset, inOffset == inEnd);
-                return false;
-            }
-        } else {
-            if (inOffset == inEnd) {
-                savePartialMultiByte(2, b1, b);
-                fPartialMultiByteResult = exitNormalize(inOffset, outOffset, true);
-                return false;
-            }
-            byte b2 = in[inOffset++];
-            if ((b2 & 0xc0) != 0x80) {
-                Object[] args = {
-                    Integer.toHexString(b & 0xff),
-                    Integer.toHexString(b1 & 0xff),
-                    Integer.toHexString(b2 & 0xff)
-                };
-                deferException(ImplementationMessages.ENC6, args, outOffset);
-                out[outOffset++] = 0;
-                return exitNormalize(inOffset, outOffset, true);
-            }
-            if ((b & 0xf0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-                int ch = ((0x0f & b)<<12) + ((0x3f & b1)<<6) + (0x3f & b2);
-                out[outOffset++] = (char)ch;
-                if (inOffset == inEnd || outOffset == outEnd) {
-                    fPartialMultiByteResult = exitNormalize(inOffset, outOffset, inOffset == inEnd);
-                    return false;
-                }
-            } else {
-                if ((b & 0xf8) != 0xf0) {
-                    Object[] args = { Integer.toHexString(b & 0xff) };
-                    deferException(ImplementationMessages.ENC4, args, outOffset);
-                    out[outOffset++] = 0;
-                    return exitNormalize(inOffset, outOffset, true);
-                }
-                if (inOffset == inEnd) {
-                    savePartialMultiByte(3, b2, b1, b);
-                    fPartialMultiByteResult = exitNormalize(inOffset, outOffset, true);
-                    return false;
-                }
-                byte b3 = in[inOffset++];
-                if ((b3 & 0xc0) != 0x80) {
-                    Object[] args = {
-                        Integer.toHexString(b & 0xff),
-                        Integer.toHexString(b1 & 0xff),
-                        Integer.toHexString(b2 & 0xff),
-                        Integer.toHexString(b3 & 0xff)
-                    };
-                    deferException(ImplementationMessages.ENC7, args, outOffset);
-                    out[outOffset++] = 0;
-                    return exitNormalize(inOffset, outOffset, true);
-                }
-                int ch = ((0x0f & b)<<18) + ((0x3f & b1)<<12) + ((0x3f & b2)<<6) + (0x3f & b3);
-                if (ch >= 0x10000) {
-                    out[outOffset++] = (char)(((ch-0x00010000)>>10)+0xd800);
-                    ch = (((ch-0x00010000)&0x3ff)+0xdc00);
-                    if (outOffset == outEnd) {
-                        fPartialSurrogatePair = ch;
-                        fPartialMultiByteResult = exitNormalize(inOffset, outOffset, inOffset == inEnd);
-                        return false;
-                    }
-                }
-                out[outOffset++] = (char)ch;
-                if (inOffset == inEnd || outOffset == outEnd) {
-                    fPartialMultiByteResult = exitNormalize(inOffset, outOffset, inOffset == inEnd);
-                    return false;
-                }
-            }
-        }
-        return exitNormalize(inOffset, outOffset, true);
-    }
-    private boolean handlePartialMultiByteChar(byte b, byte[] in, int inOffset, int inEnd, char[] out, int outOffset, int outEnd) throws Exception {
-        if (outOffset == outEnd) {
-            fPartialMultiByteResult = exitNormalize(inOffset, outOffset, inOffset == inEnd);
-            return false;
-        }
-        if (fPartialMultiByteIn == 4) {
-            out[outOffset++] = (char)fPartialSurrogatePair;
-            if (outOffset == outEnd) {
-                fPartialMultiByteResult = exitNormalize(inOffset, outOffset, false);
-                return false;
-            }
-            fOutputOffset = outOffset;
-            return true;
-        }
-        int byteIn = fPartialMultiByteIn;
-        fPartialMultiByteIn = 0;
-        byte b1 = 0;
-        byte b2 = 0;
-        byte b3 = 0;
-        switch (byteIn) {
-        case 1: b1 = b; break;
-        case 2: b2 = b; break;
-        case 3: b3 = b; break;
-        }
-        int i = byteIn;
-        switch (byteIn) {
-        case 3:
-            b2 = fPartialMultiByteChar[--i];
-        case 2:
-            b1 = fPartialMultiByteChar[--i];
-        case 1:
-            b = fPartialMultiByteChar[--i];
-        }
-        switch (byteIn) {
-        case 1:
-            if ((b1 & 0xc0) != 0x80) {
-                Object[] args = {
-                    Integer.toHexString(b),
-                    Integer.toHexString(b1)
-                };
-                deferException(ImplementationMessages.ENC5, args, outOffset);
-                out[outOffset++] = 0;
-                break;
-            }
-            // fall through
-        case 2:
-            if ((b & 0xe0) == 0xc0) { // 110yyyyy 10xxxxxx
-                int ch = ((0x1f & b)<<6) + (0x3f & b1);
-                out[outOffset++] = (char)ch;
-                if (outOffset == outEnd) {
-                    fPartialMultiByteResult = exitNormalize(inOffset, outOffset, false);
-                    return false;
-                }
-                if (byteIn < 2 && ++inOffset == inEnd) {
-                    fPartialMultiByteResult = exitNormalize(inOffset, outOffset, true);
-                    return false;
-                }
-                break;
-            }
-            if (byteIn < 2) {
-                if (++inOffset == inEnd) {
-                    savePartialMultiByte(2, b1);
-                    fPartialMultiByteResult = exitNormalize(inOffset, outOffset, true);
-                    return false;
-                }
-                b2 = in[inOffset];
-            }
-            if ((b2 & 0xc0) != 0x80) {
-                Object[] args = {
-                    Integer.toHexString(b),
-                    Integer.toHexString(b1),
-                    Integer.toHexString(b2)
-                };
-                deferException(ImplementationMessages.ENC6, args, outOffset);
-                out[outOffset++] = 0;
-                break;
-            }
-            // fall through
-        case 3:
-            if ((b & 0xf0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-                int ch = ((0x0f & b)<<12) + ((0x3f & b1)<<6) + (0x3f & b2);
-                out[outOffset++] = (char)ch;
-                if (outOffset == outEnd) {
-                    fPartialMultiByteResult = exitNormalize(inOffset, outOffset, false);
-                    return false;
-                }
-                if (byteIn < 3 && ++inOffset == inEnd) {
-                    fPartialMultiByteResult = exitNormalize(inOffset, outOffset, true);
-                    return false;
-                }
-                break;
-            }
-            if (byteIn < 3) {
-                if ((b & 0xf8) != 0xf0) {
-                    Object[] args = { Integer.toHexString(b) };
-                    deferException(ImplementationMessages.ENC4, args, outOffset);
-                    out[outOffset++] = 0;
-                    break;
-                }
-                if (++inOffset == inEnd) {
-                    savePartialMultiByte(3, b2, b1);
-                    fPartialMultiByteResult = exitNormalize(inOffset, outOffset, true);
-                    return false;
-                }
-                b3 = in[inOffset];
-            }
-            if ((b3 & 0xc0) != 0x80) {
-                Object[] args = {
-                    Integer.toHexString(b),
-                    Integer.toHexString(b1),
-                    Integer.toHexString(b2),
-                    Integer.toHexString(b3)
-                };
-                deferException(ImplementationMessages.ENC7, args, outOffset);
-                out[outOffset++] = 0;
-                break;
-            }
-            int ch = ((0x0f & b)<<18) + ((0x3f & b1)<<12) + ((0x3f & b2)<<6) + (0x3f & b3);
-            if (ch >= 0x10000) {
-                out[outOffset++] = (char)(((ch-0x00010000)>>10)+0xd800);
-                ch = (((ch-0x00010000)&0x3ff)+0xdc00);
-                if (outOffset == outEnd) {
-                    fPartialSurrogatePair = ch;
-                    fPartialMultiByteResult = exitNormalize(inOffset, outOffset, false);
-                    return false;
-                }
-            }
-            out[outOffset++] = (char)ch;
-            if (outOffset == outEnd) {
-                fPartialMultiByteResult = exitNormalize(inOffset, outOffset, false);
-                return false;
-            }
-            if (++inOffset == inEnd) {
-                fPartialMultiByteResult = exitNormalize(inOffset, outOffset, true);
-                return false;
-            }
-            break;
-        }
-        return exitNormalize(inOffset, outOffset, true);
-    }
-}
diff --git a/src/org/apache/xerces/readers/UTF8Reader.java b/src/org/apache/xerces/readers/UTF8Reader.java
deleted file mode 100644
index ddc0dab..0000000
--- a/src/org/apache/xerces/readers/UTF8Reader.java
+++ /dev/null
@@ -1,2779 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.utils.SymbolCache;
-import org.apache.xerces.utils.UTF8DataChunk;
-import org.apache.xerces.utils.XMLCharacterProperties;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.helpers.LocatorImpl;
-import java.io.InputStream;
-import java.util.Vector;
-
-/**
- * This is the primary reader used for UTF-8 encoded byte streams.
- * <p>
- * This reader processes requests from the scanners against the
- * underlying UTF-8 byte stream, avoiding when possible any up-front
- * transcoding.  When the StringPool handle interfaces are used,
- * the information in the data stream will be added to the string
- * pool and lazy-evaluated until asked for.
- * <p>
- * We use the SymbolCache to match expected names (element types in
- * end tags) and walk the data structures of that class directly.
- * <p>
- * There is a significant amount of hand-inlining and some blatant
- * voilation of good object oriented programming rules, ignoring
- * boundaries of modularity, etc., in the name of good performance.
- * <p>
- * There are also some places where the code here frequently crashes
- * the SUN java runtime compiler (JIT) and the code here has been
- * carefully "crafted" to avoid those problems.
- * 
- * @version $Id$
- */
-final class UTF8Reader extends XMLEntityReader {
-    //
-    //
-    //
-    private final static boolean USE_OUT_OF_LINE_LOAD_NEXT_BYTE = false;
-    private final static boolean USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE = true;
-    //
-    //
-    //
-    public UTF8Reader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter, boolean sendCharDataAsCharArray, InputStream dataStream, StringPool stringPool) throws Exception {
-        super(entityHandler, errorReporter, sendCharDataAsCharArray);
-        fInputStream = dataStream;
-        fStringPool = stringPool;
-        fCharArrayRange = fStringPool.createCharArrayRange();
-        fCurrentChunk = UTF8DataChunk.createChunk(fStringPool, null);
-        fillCurrentChunk();
-    }
-    /**
-     *
-     */
-    public int addString(int offset, int length) {
-        if (length == 0)
-            return 0;
-        return fCurrentChunk.addString(offset, length);
-    }
-    /**
-     *
-     */
-    public int addSymbol(int offset, int length) {
-        if (length == 0)
-            return 0;
-        return fCurrentChunk.addSymbol(offset, length, 0);
-    }
-    /**
-     *
-     */
-    private int addSymbol(int offset, int length, int hashcode) {
-        if (length == 0)
-            return 0;
-        return fCurrentChunk.addSymbol(offset, length, hashcode);
-    }
-    /**
-     *
-     */
-    public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length) {
-        fCurrentChunk.append(charBuffer, offset, length);
-    }
-    //
-    //
-    //
-    private int slowLoadNextByte()  throws Exception {
-        fCallClearPreviousChunk = true;
-        if (fCurrentChunk.nextChunk() != null) {
-            fCurrentChunk = fCurrentChunk.nextChunk();
-            fCurrentIndex = 0;
-            fMostRecentData = fCurrentChunk.toByteArray();
-            return(fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-        } else {
-            fCurrentChunk = UTF8DataChunk.createChunk(fStringPool, fCurrentChunk);
-            return fillCurrentChunk();
-        }
-    }
-    private int loadNextByte() throws Exception {
-        fCurrentOffset++;
-        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-            fCurrentIndex++;
-            try {
-                fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                return fMostRecentByte;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                return slowLoadNextByte();
-            }
-        } else {
-            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                return slowLoadNextByte();
-            else
-                return(fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-        }
-    }
-    //
-    //
-    //
-    private boolean atEOF(int offset) {
-        return(offset > fLength);
-    }
-    //
-    //
-    //
-    public XMLEntityHandler.EntityReader changeReaders() throws Exception {
-        XMLEntityHandler.EntityReader nextReader = super.changeReaders();
-        fCurrentChunk.releaseChunk();
-        fCurrentChunk = null;
-        fMostRecentData = null;
-        fMostRecentByte = 0;
-        return nextReader;
-    }
-    //
-    //
-    //
-    public boolean lookingAtChar(char ch, boolean skipPastChar) throws Exception {
-        int b0 = fMostRecentByte;
-        if (b0 != ch) {
-            if (b0 == 0) {
-                if (atEOF(fCurrentOffset + 1)) {
-                    return changeReaders().lookingAtChar(ch, skipPastChar);
-                }
-            }
-            if (ch == 0x0A && b0 == 0x0D) {
-                if (skipPastChar) {
-                    fCarriageReturnCounter++;
-                    fCharacterCounter = 1;
-                    if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                        b0 = loadNextByte();
-                    } else {
-                        fCurrentOffset++;
-                        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                            fCurrentIndex++;
-                            try {
-                                fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                                b0 = fMostRecentByte;
-                            } catch (ArrayIndexOutOfBoundsException ex) {
-                                b0 = slowLoadNextByte();
-                            }
-                        } else {
-                            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                b0 = slowLoadNextByte();
-                            else
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        }
-                    }
-                    if (b0 == 0x0A) {
-                        fLinefeedCounter++;
-                        if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                            loadNextByte();
-                        } else {
-                            fCurrentOffset++;
-                            if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                                fCurrentIndex++;
-                                try {
-                                    fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                                } catch (ArrayIndexOutOfBoundsException ex) {
-                                    slowLoadNextByte();
-                                }
-                            } else {
-                                if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                    slowLoadNextByte();
-                                else
-                                    fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                            }
-                        }
-                    }
-                }
-                return true;
-            }
-            return false;
-        }
-        if (ch == 0x0D)
-            return false;
-        if (skipPastChar) {
-            fCharacterCounter++;
-            if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                loadNextByte();
-            } else {
-                fCurrentOffset++;
-                if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                    fCurrentIndex++;
-                    try {
-                        fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                    } catch (ArrayIndexOutOfBoundsException ex) {
-                        slowLoadNextByte();
-                    }
-                } else {
-                    if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                        slowLoadNextByte();
-                    else
-                        fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                }
-            }
-        }
-        return true;
-    }
-    //
-    //
-    //
-    public boolean lookingAtValidChar(boolean skipPastChar) throws Exception {
-        int b0 = fMostRecentByte;
-        if (b0 < 0x80) {  // 0xxxxxxx
-            if (b0 >= 0x20 || b0 == 0x09) {
-                if (skipPastChar) {
-                    fCharacterCounter++;
-                    if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                        loadNextByte();
-                    } else {
-                        fCurrentOffset++;
-                        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                            fCurrentIndex++;
-                            try {
-                                fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                            } catch (ArrayIndexOutOfBoundsException ex) {
-                                slowLoadNextByte();
-                            }
-                        } else {
-                            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                slowLoadNextByte();
-                            else
-                                fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                        }
-                    }
-                }
-                return true;
-            }
-            if (b0 == 0x0A) {
-                if (skipPastChar) {
-                    fLinefeedCounter++;
-                    fCharacterCounter = 1;
-                    if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                        loadNextByte();
-                    } else {
-                        fCurrentOffset++;
-                        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                            fCurrentIndex++;
-                            try {
-                                fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                            } catch (ArrayIndexOutOfBoundsException ex) {
-                                slowLoadNextByte();
-                            }
-                        } else {
-                            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                slowLoadNextByte();
-                            else
-                                fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                        }
-                    }
-                }
-                return true;
-            }
-            if (b0 == 0x0D) {
-                if (skipPastChar) {
-                    fCarriageReturnCounter++;
-                    fCharacterCounter = 1;
-                    if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                        b0 = loadNextByte();
-                    } else {
-                        fCurrentOffset++;
-                        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                            fCurrentIndex++;
-                            try {
-                                fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                                b0 = fMostRecentByte;
-                            } catch (ArrayIndexOutOfBoundsException ex) {
-                                b0 = slowLoadNextByte();
-                            }
-                        } else {
-                            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                b0 = slowLoadNextByte();
-                            else
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        }
-                    }
-                    if (b0 == 0x0A) {
-                        fLinefeedCounter++;
-                        if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                            loadNextByte();
-                        } else {
-                            fCurrentOffset++;
-                            if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                                fCurrentIndex++;
-                                try {
-                                    fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                                } catch (ArrayIndexOutOfBoundsException ex) {
-                                    slowLoadNextByte();
-                                }
-                            } else {
-                                if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                    slowLoadNextByte();
-                                else
-                                    fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                            }
-                        }
-                    }
-                }
-                return true;
-            }
-            if (b0 == 0) {
-                if (atEOF(fCurrentOffset + 1)) {
-                    return changeReaders().lookingAtValidChar(skipPastChar);
-                }
-            }
-            return false;
-        }
-        //
-        // REVISIT - optimize this with in-buffer lookahead.
-        //
-        UTF8DataChunk saveChunk = fCurrentChunk;
-        int saveIndex = fCurrentIndex;
-        int saveOffset = fCurrentOffset;
-        int b1 = loadNextByte();
-        if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx (0x80 to 0x7ff)
-            if (skipPastChar) {
-                fCharacterCounter++;
-                loadNextByte();
-            } else {
-                fCurrentChunk = saveChunk;
-                fCurrentIndex = saveIndex;
-                fCurrentOffset = saveOffset;
-                fMostRecentData = saveChunk.toByteArray();
-                fMostRecentByte = b0;
-            }
-            return true; // [#x20-#xD7FF]
-        }
-        int b2 = loadNextByte();
-        if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-            // ch = ((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2); // zzzz yyyy yyxx xxxx (0x800 to 0xffff)
-            // if (!((ch >= 0xD800 && ch <= 0xDFFF) || ch >= 0xFFFE))
-            // if ((ch <= 0xD7FF) || (ch >= 0xE000 && ch <= 0xFFFD))
-            boolean result = false;
-            if (!((b0 == 0xED && b1 >= 0xA0) || (b0 == 0xEF && b1 == 0xBF && b2 >= 0xBE))) { // [#x20-#xD7FF] | [#xE000-#xFFFD]
-                if (skipPastChar) {
-                    fCharacterCounter++;
-                    loadNextByte();
-                    return true;
-                }
-                result = true;
-            }
-            fCurrentChunk = saveChunk;
-            fCurrentIndex = saveIndex;
-            fCurrentOffset = saveOffset;
-            fMostRecentData = saveChunk.toByteArray();
-            fMostRecentByte = b0;
-            return result;
-        }
-        int b3 = loadNextByte();  // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-        // ch = ((0x0f & b0)<<18) + ((0x3f & b1)<<12) + ((0x3f & b2)<<6) + (0x3f & b3); // u uuuu zzzz yyyy yyxx xxxx (0x10000 to 0x1ffff)
-        // if (ch >= 0x110000)
-        boolean result = false;
-
-        //if (( 0xf8 & b0 ) == 0xf0 ) {
-            //if (!(b0 > 0xF4 || (b0 == 0xF4 && b1 >= 0x90))) { // [#x10000-#x10FFFF]
-        if( ((b0&0xf8) == 0xf0) && ((b1&0xc0)==0x80) &&
-            ((b2&0xc0) == 0x80) && ((b3&0xc0)==0x80)){
-            if (skipPastChar) {
-                    fCharacterCounter++;
-                    loadNextByte();
-                    return true;
-            }
-            result = true;
-            //}
-            fCurrentChunk = saveChunk;
-            fCurrentIndex = saveIndex;
-            fCurrentOffset = saveOffset;
-            fMostRecentData = saveChunk.toByteArray();
-            fMostRecentByte = b0;
-            return result;
-        } else{
-            fCurrentChunk = saveChunk;
-            fCurrentIndex = saveIndex;
-            fCurrentOffset = saveOffset;
-            fMostRecentData = saveChunk.toByteArray();
-            fMostRecentByte = b0;
-            return result;
-        }
-    }
-    //
-    //
-    //
-    public boolean lookingAtSpace(boolean skipPastChar) throws Exception {
-        int ch = fMostRecentByte;
-        if (ch > 0x20)
-            return false;
-        if (ch == 0x20 || ch == 0x09) {
-            if (!skipPastChar)
-                return true;
-            fCharacterCounter++;
-        } else if (ch == 0x0A) {
-            if (!skipPastChar)
-                return true;
-            fLinefeedCounter++;
-            fCharacterCounter = 1;
-        } else if (ch == 0x0D) {
-            if (!skipPastChar)
-                return true;
-            fCarriageReturnCounter++;
-            fCharacterCounter = 1;
-            if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                ch = loadNextByte();
-            } else {
-                fCurrentOffset++;
-                if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                    fCurrentIndex++;
-                    try {
-                        fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                        ch = fMostRecentByte;
-                    } catch (ArrayIndexOutOfBoundsException ex) {
-                        ch = slowLoadNextByte();
-                    }
-                } else {
-                    if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                        ch = slowLoadNextByte();
-                    else
-                        ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                }
-            }
-            if (ch != 0x0A)
-                return true;
-            fLinefeedCounter++;
-        } else {
-            if (ch == 0) { // REVISIT - should we be checking this here ?
-                if (atEOF(fCurrentOffset + 1)) {
-                    return changeReaders().lookingAtSpace(skipPastChar);
-                }
-            }
-            return false;
-        }
-        if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-            loadNextByte();
-        } else {
-            fCurrentOffset++;
-            if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                fCurrentIndex++;
-                try {
-                    fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                } catch (ArrayIndexOutOfBoundsException ex) {
-                    slowLoadNextByte();
-                }
-            } else {
-                if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                    slowLoadNextByte();
-                else
-                    fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-            }
-        }
-        return true;
-    }
-    //
-    //
-    //
-    public void skipToChar(char ch) throws Exception {
-        //
-        // REVISIT - this will skip invalid characters without reporting them.
-        //
-        int b0 = fMostRecentByte;
-        while (true) {
-            if (b0 == ch) // ch will always be an ascii character
-                return;
-            if (b0 == 0) {
-                if (atEOF(fCurrentOffset + 1)) {
-                    changeReaders().skipToChar(ch);
-                    return;
-                }
-                fCharacterCounter++;
-            } else if (b0 == 0x0A) {
-                fLinefeedCounter++;
-                fCharacterCounter = 1;
-            } else if (b0 == 0x0D) {
-                fCarriageReturnCounter++;
-                fCharacterCounter = 1;
-                b0 = loadNextByte();
-                if (b0 != 0x0A)
-                    continue;
-                fLinefeedCounter++;
-            } else if (b0 < 0x80) { // 0xxxxxxx
-                fCharacterCounter++;
-            } else {
-                fCharacterCounter++;
-                if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx
-                    loadNextByte();
-                } else if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-                    loadNextByte();
-                    loadNextByte();
-                } else { // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-                    loadNextByte();
-                    loadNextByte();
-                    loadNextByte();
-                }
-            }
-            b0 = loadNextByte();
-        }
-    }
-    //
-    //
-    //
-    public void skipPastSpaces() throws Exception {
-        int ch = fMostRecentByte;
-        while (true) {
-            if (ch == 0x20 || ch == 0x09) {
-                fCharacterCounter++;
-            } else if (ch == 0x0A) {
-                fLinefeedCounter++;
-                fCharacterCounter = 1;
-            } else if (ch == 0x0D) {
-                fCarriageReturnCounter++;
-                fCharacterCounter = 1;
-                if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                    ch = loadNextByte();
-                } else {
-                    fCurrentOffset++;
-                    if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                        fCurrentIndex++;
-                        try {
-                            fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                            ch = fMostRecentByte;
-                        } catch (ArrayIndexOutOfBoundsException ex) {
-                            ch = slowLoadNextByte();
-                        }
-                    } else {
-                        if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                            ch = slowLoadNextByte();
-                        else
-                            ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                    }
-                }
-                if (ch != 0x0A)
-                    continue;
-                fLinefeedCounter++;
-            } else {
-                if (ch == 0 && atEOF(fCurrentOffset + 1))
-                    changeReaders().skipPastSpaces();
-                return;
-            }
-            if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                ch = loadNextByte();
-            } else {
-                fCurrentOffset++;
-                if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                    fCurrentIndex++;
-                    try {
-                        fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                        ch = fMostRecentByte;
-                    } catch (ArrayIndexOutOfBoundsException ex) {
-                        ch = slowLoadNextByte();
-                    }
-                } else {
-                    if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                        ch = slowLoadNextByte();
-                    else
-                        ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                }
-            }
-        }
-    }
-    //
-    //
-    //
-    protected boolean skippedMultiByteCharWithFlag(int b0, int flag) throws Exception {
-        UTF8DataChunk saveChunk = fCurrentChunk;
-        int saveOffset = fCurrentOffset;
-        int saveIndex = fCurrentIndex;
-        if (!fCalledCharPropInit) {
-            XMLCharacterProperties.initCharFlags();
-            fCalledCharPropInit = true;
-        }
-        int b1 = loadNextByte();
-        if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx
-            if ((XMLCharacterProperties.fgCharFlags[((0x1f & b0)<<6) + (0x3f & b1)] & flag) == 0) { // yyy yyxx xxxx (0x80 to 0x7ff)
-                fCurrentChunk = saveChunk;
-                fCurrentIndex = saveIndex;
-                fCurrentOffset = saveOffset;
-                fMostRecentData = saveChunk.toByteArray();
-                fMostRecentByte = b0;
-                return false;
-            }
-            return true;
-        }
-        int b2 = loadNextByte();
-        if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-            // if ((ch >= 0xD800 && ch <= 0xDFFF) || ch >= 0xFFFE)
-            if ((b0 == 0xED && b1 >= 0xA0) || (b0 == 0xEF && b1 == 0xBF && b2 >= 0xBE)) {
-                fCurrentChunk = saveChunk;
-                fCurrentIndex = saveIndex;
-                fCurrentOffset = saveOffset;
-                fMostRecentData = saveChunk.toByteArray();
-                fMostRecentByte = b0;
-                return false;
-            }
-            if ((XMLCharacterProperties.fgCharFlags[((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2)] & flag) == 0) { // zzzz yyyy yyxx xxxx (0x800 to 0xffff)
-                fCurrentChunk = saveChunk;
-                fCurrentIndex = saveIndex;
-                fCurrentOffset = saveOffset;
-                fMostRecentData = saveChunk.toByteArray();
-                fMostRecentByte = b0;
-                return false;
-            }
-            return true;
-        } else { // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-            fCurrentChunk = saveChunk;
-            fCurrentIndex = saveIndex;
-            fCurrentOffset = saveOffset;
-            fMostRecentData = saveChunk.toByteArray();
-            fMostRecentByte = b0;
-            return false;
-        }
-    }
-    public void skipPastName(char fastcheck) throws Exception {
-        int b0 = fMostRecentByte;
-        if (b0 < 0x80) {
-            if (XMLCharacterProperties.fgAsciiInitialNameChar[b0] == 0)
-                return;
-        } else {
-            if (!fCalledCharPropInit) {
-                XMLCharacterProperties.initCharFlags();
-                fCalledCharPropInit = true;
-            }
-            if (!skippedMultiByteCharWithFlag(b0, XMLCharacterProperties.E_InitialNameCharFlag))
-                return;
-        }
-        while (true) {
-            fCharacterCounter++;
-            b0 = loadNextByte();
-            if (fastcheck == b0)
-                return;
-            if (b0 < 0x80) {
-                if (XMLCharacterProperties.fgAsciiNameChar[b0] == 0)
-                    return;
-            } else {
-                if (!fCalledCharPropInit) {
-                    XMLCharacterProperties.initCharFlags();
-                    fCalledCharPropInit = true;
-                }
-                if (!skippedMultiByteCharWithFlag(b0, XMLCharacterProperties.E_NameCharFlag))
-                    return;
-            }
-        }
-    }
-    //
-    //
-    //
-    public void skipPastNmtoken(char fastcheck) throws Exception {
-        int b0 = fMostRecentByte;
-        while (true) {
-            if (fastcheck == b0)
-                return;
-            if (b0 < 0x80) {
-                if (XMLCharacterProperties.fgAsciiNameChar[b0] == 0)
-                    return;
-            } else {
-                if (!skippedMultiByteCharWithFlag(b0, XMLCharacterProperties.E_NameCharFlag))
-                    return;
-            }
-            fCharacterCounter++;
-            b0 = loadNextByte();
-        }
-    }
-    //
-    //
-    //
-    public boolean skippedString(char[] s) throws Exception {
-        int length = s.length;
-        byte[] data = fMostRecentData;
-        int index = fCurrentIndex + length;
-        int sindex = length;
-        try {
-            while (sindex-- > 0) {
-                if (data[--index] != s[sindex])
-                    return false;
-            }
-            fCurrentIndex += length;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            int i = 0;
-            index = fCurrentIndex;
-            while (index < UTF8DataChunk.CHUNK_SIZE) {
-                if (data[index++] != s[i++])
-                    return false;
-            }
-            UTF8DataChunk dataChunk = fCurrentChunk;
-            int savedOffset = fCurrentOffset;
-            int savedIndex = fCurrentIndex;
-            slowLoadNextByte();
-            data = fMostRecentData;
-            index = 0;
-            while (i < length) {
-                if (data[index++] != s[i++]) {
-                    fCurrentChunk = dataChunk;
-                    fCurrentIndex = savedIndex;
-                    fCurrentOffset = savedOffset;
-                    fMostRecentData = fCurrentChunk.toByteArray();
-                    fMostRecentByte = fMostRecentData[savedIndex] & 0xFF;
-                    return false;
-                }
-            }
-            fCurrentIndex = index;
-        }
-        fCharacterCounter += length;
-        fCurrentOffset += length;
-        try {
-            fMostRecentByte = data[fCurrentIndex] & 0xFF;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            slowLoadNextByte();
-        }
-        return true;
-    }
-    //
-    //
-    //
-    public int scanInvalidChar() throws Exception {
-        int b0 = fMostRecentByte;
-        int ch = b0;
-        if (ch == 0x0A) {
-            fLinefeedCounter++;
-            fCharacterCounter = 1;
-        } else if (ch == 0x0D) {
-            fCarriageReturnCounter++;
-            fCharacterCounter = 1;
-            ch = loadNextByte();
-            if (ch != 0x0A)
-                return 0x0A;
-            fLinefeedCounter++;
-        } else if (ch == 0) {
-            if (atEOF(fCurrentOffset + 1)) {
-                return changeReaders().scanInvalidChar();
-            }
-            fCharacterCounter++;
-        } else if (b0 >= 0x80) {
-            fCharacterCounter++;
-            int b1 = loadNextByte();
-            int b2 = 0;
-            if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx
-                ch = ((0x1f & b0)<<6) + (0x3f & b1);
-            } else if( (0xf0 & b0) == 0xe0 ) { 
-                b2 = loadNextByte();
-                ch = ((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2);
-            } else if(( 0xf8 & b0 ) == 0xf0 ){
-                b2 = loadNextByte();
-                int b3 = loadNextByte(); // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-                ch = ((0x0f & b0)<<18) + ((0x3f & b1)<<12)
-                         + ((0x3f & b2)<<6) + (0x3f & b3);
-            }
-        }
-        loadNextByte();
-        return ch;
-    }
-    //
-    //
-    //
-    public int scanCharRef(boolean hex) throws Exception {
-        int ch = fMostRecentByte;
-        if (ch == 0) {
-            if (atEOF(fCurrentOffset + 1)) {
-                return changeReaders().scanCharRef(hex);
-            }
-            return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-        }
-        int num = 0;
-        if (hex) {
-            if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
-                return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-            num = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
-        } else {
-            if (ch < '0' || ch > '9')
-                return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
-            num = ch - '0';
-        }
-        fCharacterCounter++;
-        loadNextByte();
-        boolean toobig = false;
-        while (true) {
-            ch = fMostRecentByte;
-            if (ch == 0)
-                break;
-            if (hex) {
-                if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
-                    break;
-            } else {
-                if (ch < '0' || ch > '9')
-                    break;
-            }
-            fCharacterCounter++;
-            loadNextByte();
-            if (hex) {
-                int dig = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
-                num = (num << 4) + dig;
-            } else {
-                int dig = ch - '0';
-                num = (num * 10) + dig;
-            }
-            if (num > 0x10FFFF) {
-                toobig = true;
-                num = 0;
-            }
-        }
-        if (ch != ';')
-            return XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED;
-        fCharacterCounter++;
-        loadNextByte();
-        if (toobig)
-            return XMLEntityHandler.CHARREF_RESULT_OUT_OF_RANGE;
-        return num;
-    }
-    //
-    //
-    //
-    public int scanStringLiteral() throws Exception {
-        boolean single;
-        if (!(single = lookingAtChar('\'', true)) && !lookingAtChar('\"', true)) {
-            return XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED;
-        }
-        int offset = fCurrentOffset;
-        char qchar = single ? '\'' : '\"';
-        while (!lookingAtChar(qchar, false)) {
-            if (!lookingAtValidChar(true)) {
-                return XMLEntityHandler.STRINGLIT_RESULT_INVALID_CHAR;
-            }
-        }
-        int stringIndex = fCurrentChunk.addString(offset, fCurrentOffset - offset);
-        lookingAtChar(qchar, true); // move past qchar
-        return stringIndex;
-    }
-    //
-    // [10] AttValue ::= '"' ([^<&"] | Reference)* '"'
-    //                   | "'" ([^<&'] | Reference)* "'"
-    //
-    // The values in the following table are defined as:
-    //
-    //      0 - not special
-    //      1 - quote character
-    //      2 - complex
-    //      3 - less than
-    //      4 - invalid
-    //
-    public static final byte fgAsciiAttValueChar[] = {
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 2, 4, 4, // tab is 0x09,  LF is 0x0A,  CR is 0x0D
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-        0, 0, 1, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, // '\"' is 0x22, '&' is 0x26, '\'' is 0x27
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, // '<' is 0x3C
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    };
-    public int scanAttValue(char qchar, boolean asSymbol) throws Exception
-    {
-        int offset = fCurrentOffset;
-        int b0 = fMostRecentByte;
-        while (true) {
-            if (b0 < 0x80) {
-                switch (fgAsciiAttValueChar[b0]) {
-                case 1: // quote char
-                    if (b0 == qchar) {
-                        int length = fCurrentOffset - offset;
-                        int result = length == 0 ? StringPool.EMPTY_STRING : (asSymbol ? fCurrentChunk.addSymbol(offset, length, 0) : fCurrentChunk.addString(offset, length));
-                        fCharacterCounter++;
-                        if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                            loadNextByte();
-                        } else {
-                            fCurrentOffset++;
-                            if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                                fCurrentIndex++;
-                                try {
-                                    fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                                } catch (ArrayIndexOutOfBoundsException ex) {
-                                    slowLoadNextByte();
-                                }
-                            } else {
-                                if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                    slowLoadNextByte();
-                                else
-                                    fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                            }
-                        }
-                        return result;
-                    }
-                    // the other quote character is not special
-                    // fall through
-                case 0: // non-special char
-                    fCharacterCounter++;
-                    if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                        b0 = loadNextByte();
-                    } else {
-                        fCurrentOffset++;
-                        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                            fCurrentIndex++;
-                            try {
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                            } catch (ArrayIndexOutOfBoundsException ex) {
-                                b0 = slowLoadNextByte();
-                            }
-                        } else {
-                            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                b0 = slowLoadNextByte();
-                            else
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        }
-                    }
-                    continue;
-                case 2: // complex
-                    return XMLEntityHandler.ATTVALUE_RESULT_COMPLEX;
-                case 3: // less than
-                    return XMLEntityHandler.ATTVALUE_RESULT_LESSTHAN;
-                case 4: // invalid
-                    return XMLEntityHandler.ATTVALUE_RESULT_INVALID_CHAR;
-                }
-            } else {
-                if (!skipMultiByteCharData(b0))
-                    return XMLEntityHandler.ATTVALUE_RESULT_INVALID_CHAR;
-                b0 = fMostRecentByte;
-            }
-        }
-    }
-    //
-    // [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
-    //                     | "'" ([^%&'] | PEReference | Reference)* "'"
-    //
-    // The values in the following table are defined as:
-    //
-    //      0 - not special
-    //      1 - quote character
-    //      2 - reference
-    //      3 - peref
-    //      4 - invalid
-    //      5 - linefeed
-    //      6 - carriage-return
-    //      7 - end of input
-    //
-    public static final byte fgAsciiEntityValueChar[] = {
-        7, 4, 4, 4, 4, 4, 4, 4, 4, 0, 5, 4, 4, 6, 4, 4, // tab is 0x09,  LF is 0x0A,  CR is 0x0D
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-        0, 0, 1, 0, 0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, // '\"', '%', '&', '\''
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    };
-    public int scanEntityValue(int qchar, boolean createString) throws Exception
-    {
-        int offset = fCurrentOffset;
-        int b0 = fMostRecentByte;
-        while (true) {
-            if (b0 < 0x80) {
-                switch (fgAsciiEntityValueChar[b0]) {
-                case 1: // quote char
-                    if (b0 == qchar) {
-                        if (!createString)
-                            return XMLEntityHandler.ENTITYVALUE_RESULT_FINISHED;
-                        int length = fCurrentOffset - offset;
-                        int result = length == 0 ? StringPool.EMPTY_STRING : fCurrentChunk.addString(offset, length);
-                        fCharacterCounter++;
-                        if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                            loadNextByte();
-                        } else {
-                            fCurrentOffset++;
-                            if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                                fCurrentIndex++;
-                                try {
-                                    fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                                } catch (ArrayIndexOutOfBoundsException ex) {
-                                    slowLoadNextByte();
-                                }
-                            } else {
-                                if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                    slowLoadNextByte();
-                                else
-                                    fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                            }
-                        }
-                        return result;
-                    }
-                    // the other quote character is not special
-                    // fall through
-                case 0: // non-special char
-                    fCharacterCounter++;
-                    if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                        b0 = loadNextByte();
-                    } else {
-                        fCurrentOffset++;
-                        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                            fCurrentIndex++;
-                            try {
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                            } catch (ArrayIndexOutOfBoundsException ex) {
-                                b0 = slowLoadNextByte();
-                            }
-                        } else {
-                            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                b0 = slowLoadNextByte();
-                            else
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        }
-                    }
-                    continue;
-                case 5: // linefeed
-                    fLinefeedCounter++;
-                    fCharacterCounter = 1;
-                    if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                        b0 = loadNextByte();
-                    } else {
-                        fCurrentOffset++;
-                        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                            fCurrentIndex++;
-                            try {
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                            } catch (ArrayIndexOutOfBoundsException ex) {
-                                b0 = slowLoadNextByte();
-                            }
-                        } else {
-                            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                b0 = slowLoadNextByte();
-                            else
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        }
-                    }
-                    continue;
-                case 6: // carriage-return
-                    fCarriageReturnCounter++;
-                    fCharacterCounter = 1;
-                    if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                        b0 = loadNextByte();
-                    } else {
-                        fCurrentOffset++;
-                        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                            fCurrentIndex++;
-                            try {
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                            } catch (ArrayIndexOutOfBoundsException ex) {
-                                b0 = slowLoadNextByte();
-                            }
-                        } else {
-                            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                b0 = slowLoadNextByte();
-                            else
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        }
-                    }
-                    if (b0 != 0x0A) {
-                        continue;
-                    }
-                    fLinefeedCounter++;
-                    if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                        b0 = loadNextByte();
-                    } else {
-                        fCurrentOffset++;
-                        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                            fCurrentIndex++;
-                            try {
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                            } catch (ArrayIndexOutOfBoundsException ex) {
-                                b0 = slowLoadNextByte();
-                            }
-                        } else {
-                            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                b0 = slowLoadNextByte();
-                            else
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        }
-                    }
-                    continue;
-                case 2: // reference
-                    return XMLEntityHandler.ENTITYVALUE_RESULT_REFERENCE;
-                case 3: // peref
-                    return XMLEntityHandler.ENTITYVALUE_RESULT_PEREF;
-                case 7:
-                    if (atEOF(fCurrentOffset + 1)) {
-                        changeReaders(); // do not call next reader, our caller may need to change the parameters
-                        return XMLEntityHandler.ENTITYVALUE_RESULT_END_OF_INPUT;
-                    }
-                    // fall into...
-                case 4: // invalid
-                    return XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR;
-                }
-            } else {
-                if (!skipMultiByteCharData(b0))
-                    return XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR;
-                b0 = fMostRecentByte;
-            }
-        }
-    }
-    //
-    //
-    //
-    public boolean scanExpectedName(char fastcheck, StringPool.CharArrayRange expectedName) throws Exception {
-        char[] expected = expectedName.chars;
-        int offset = expectedName.offset;
-        int len = expectedName.length;
-        int b0 = fMostRecentByte;
-        int ch = 0;
-        int i = 0;
-        while (true) {
-            if (b0 < 0x80) {
-                ch = b0;
-                if (i == len)
-                    break;
-                if (ch != expected[offset]) {
-                    skipPastNmtoken(fastcheck);
-                    return false;
-                }
-            } else {
-                //
-                // REVISIT - optimize this with in-buffer lookahead.
-                //
-                UTF8DataChunk saveChunk = fCurrentChunk;
-                int saveIndex = fCurrentIndex;
-                int saveOffset = fCurrentOffset;
-                int b1;
-                if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                    b1 = loadNextByte();
-                } else {
-                    fCurrentOffset++;
-                    if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                        fCurrentIndex++;
-                        try {
-                            b1 = fMostRecentData[fCurrentIndex] & 0xFF;
-                        } catch (ArrayIndexOutOfBoundsException ex) {
-                            b1 = slowLoadNextByte();
-                        }
-                    } else {
-                        if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                            b1 = slowLoadNextByte();
-                        else
-                            b1 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                    }
-                }
-                if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx
-                    ch = ((0x1f & b0)<<6) + (0x3f & b1);
-                    if (i == len)
-                        break;
-                    if (ch != expected[offset]) {
-                        fCurrentChunk = saveChunk;
-                        fCurrentIndex = saveIndex;
-                        fCurrentOffset = saveOffset;
-                        fMostRecentData = saveChunk.toByteArray();
-                        fMostRecentByte = b0;
-                        skipPastNmtoken(fastcheck);
-                        return false;
-                    }
-                } else {
-                    int b2;
-                    if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                        b2 = loadNextByte();
-                    } else {
-                        fCurrentOffset++;
-                        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                            fCurrentIndex++;
-                            try {
-                                b2 = fMostRecentData[fCurrentIndex] & 0xFF;
-                            } catch (ArrayIndexOutOfBoundsException ex) {
-                                b2 = slowLoadNextByte();
-                            }
-                        } else {
-                            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                b2 = slowLoadNextByte();
-                            else
-                                b2 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        }
-                    }
-                    if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-                        // if ((ch >= 0xD800 && ch <= 0xDFFF) || ch >= 0xFFFE)
-                        if ((b0 == 0xED && b1 >= 0xA0) || (b0 == 0xEF && b1 == 0xBF && b2 >= 0xBE)) {
-                            fCurrentChunk = saveChunk;
-                            fCurrentIndex = saveIndex;
-                            fCurrentOffset = saveOffset;
-                            fMostRecentData = saveChunk.toByteArray();
-                            fMostRecentByte = b0;
-                            return false;
-                        }
-                        ch = ((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2);
-                        if (i == len)
-                            break;
-                        if (ch != expected[offset]) {
-                            fCurrentChunk = saveChunk;
-                            fCurrentIndex = saveIndex;
-                            fCurrentOffset = saveOffset;
-                            fMostRecentData = saveChunk.toByteArray();
-                            fMostRecentByte = b0;
-                            skipPastNmtoken(fastcheck);
-                            return false;
-                        }
-                    } else { // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-                        fCurrentChunk = saveChunk;
-                        fCurrentIndex = saveIndex;
-                        fCurrentOffset = saveOffset;
-                        fMostRecentData = saveChunk.toByteArray();
-                        fMostRecentByte = b0;
-                        return false;
-                    }
-                }
-            }
-            i++;
-            offset++;
-            fCharacterCounter++;
-            fCurrentOffset++;
-            if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                fCurrentIndex++;
-                try {
-                    b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                } catch (ArrayIndexOutOfBoundsException ex) {
-                    b0 = slowLoadNextByte();
-                }
-            } else {
-                if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                    b0 = slowLoadNextByte();
-                else
-                    b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-            }
-        }
-        if (ch == fastcheck)
-            return true;
-        if (ch < 0x80) {
-            if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                return true;
-        } else {
-            if (!fCalledCharPropInit) {
-                XMLCharacterProperties.initCharFlags();
-                fCalledCharPropInit = true;
-            }
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                return true;
-        }
-        skipPastNmtoken(fastcheck);
-        return false;
-    }
-
-    public void scanQName(char fastcheck, QName qname) throws Exception {
-
-        int ch = fMostRecentByte;
-        if (ch < 0x80) {
-            if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0) {
-                qname.clear();
-                return;
-            }
-            if (ch == ':') {
-                qname.clear();
-                return;
-            }
-        } else {
-            if (!fCalledCharPropInit) {
-                XMLCharacterProperties.initCharFlags();
-                fCalledCharPropInit = true;
-            }
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0) {
-                qname.clear();
-                return;
-            }
-        }
-        int offset = fCurrentOffset;
-        int index = fCurrentIndex;
-        byte[] data = fMostRecentData;
-        int prefixend = -1;
-        while (true) {
-            fCharacterCounter++;
-            fCurrentOffset++;
-            index++;
-            try {
-                ch = data[index] & 0xFF;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                ch = slowLoadNextByte();
-                index = 0;
-                data = fMostRecentData;
-            }
-            if (fastcheck == ch)
-                break;
-            if (ch < 0x80) {
-                if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
-                    break;
-                if (ch == ':') {
-                    if (prefixend != -1)
-                        break;
-                    prefixend = fCurrentOffset;
-                    //
-                    // We need to peek ahead one character.  If the next character is not a
-                    // valid initial name character, or is another colon, then we cannot meet
-                    // both the Prefix and LocalPart productions for the QName production,
-                    // which means that there is no Prefix and we need to terminate the QName
-                    // at the first colon.
-                    //
-                    try {
-                        ch = data[index + 1] & 0xFF;
-                    } catch (ArrayIndexOutOfBoundsException ex) {
-                        UTF8DataChunk savedChunk = fCurrentChunk;
-                        int savedOffset = fCurrentOffset;
-                        ch = slowLoadNextByte();
-                        fCurrentChunk = savedChunk;
-                        fCurrentOffset = savedOffset;
-                        fMostRecentData = fCurrentChunk.toByteArray();
-                    }
-                    boolean lpok = true;
-                    if (ch < 0x80) {
-                        if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0 || ch == ':')
-                            lpok = false;
-                    } else {
-                        if (!fCalledCharPropInit) {
-                            XMLCharacterProperties.initCharFlags();
-                            fCalledCharPropInit = true;
-                        }
-                        if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
-                            lpok = false;
-                    }
-                    ch = ':';
-                    if (!lpok) {
-                        prefixend = -1;
-                        break;
-                    }
-                }
-            } else {
-                if (!fCalledCharPropInit) {
-                    XMLCharacterProperties.initCharFlags();
-                    fCalledCharPropInit = true;
-                }
-                if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
-                    break;
-            }
-        }
-        fCurrentIndex = index;
-        fMostRecentByte = ch;
-        int length = fCurrentOffset - offset;
-        qname.rawname = addSymbol(offset, length);
-        qname.prefix = prefixend == -1 ? -1 : addSymbol(offset, prefixend - offset);
-        qname.localpart = prefixend == -1 ? qname.rawname : addSymbol(prefixend + 1, fCurrentOffset - (prefixend + 1));
-        qname.uri = -1;
-
-    } // scanQName(char,QName)
-
-    private int getMultiByteSymbolChar(int b0) throws Exception {
-        //
-        // REVISIT - optimize this with in-buffer lookahead.
-        //
-        UTF8DataChunk saveChunk = fCurrentChunk;
-        int saveIndex = fCurrentIndex;
-        int saveOffset = fCurrentOffset;
-        if (!fCalledCharPropInit) {
-            XMLCharacterProperties.initCharFlags();
-            fCalledCharPropInit = true;
-        }
-        int b1;
-        if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-            b1 = loadNextByte();
-        } else {
-            fCurrentOffset++;
-            if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                fCurrentIndex++;
-                try {
-                    b1 = fMostRecentData[fCurrentIndex] & 0xFF;
-                } catch (ArrayIndexOutOfBoundsException ex) {
-                    b1 = slowLoadNextByte();
-                }
-            } else {
-                if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                    b1 = slowLoadNextByte();
-                else
-                    b1 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-            }
-        }
-        if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx
-            int ch = ((0x1f & b0)<<6) + (0x3f & b1);
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0) { // yyy yyxx xxxx (0x80 to 0x7ff)
-                fCurrentChunk = saveChunk;
-                fCurrentIndex = saveIndex;
-                fCurrentOffset = saveOffset;
-                fMostRecentData = saveChunk.toByteArray();
-                fMostRecentByte = b0;
-                return -1;
-            }
-            loadNextByte();
-            return ch;
-        }
-        int b2;
-        if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-            b2 = loadNextByte();
-        } else {
-            fCurrentOffset++;
-            if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                fCurrentIndex++;
-                try {
-                    b2 = fMostRecentData[fCurrentIndex] & 0xFF;
-                } catch (ArrayIndexOutOfBoundsException ex) {
-                    b2 = slowLoadNextByte();
-                }
-            } else {
-                if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                    b2 = slowLoadNextByte();
-                else
-                    b2 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-            }
-        }
-        if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-            // if ((ch >= 0xD800 && ch <= 0xDFFF) || ch >= 0xFFFE)
-            if ((b0 == 0xED && b1 >= 0xA0) || (b0 == 0xEF && b1 == 0xBF && b2 >= 0xBE)) {
-                fCurrentChunk = saveChunk;
-                fCurrentIndex = saveIndex;
-                fCurrentOffset = saveOffset;
-                fMostRecentData = saveChunk.toByteArray();
-                fMostRecentByte = b0;
-                return -1;
-            }
-            int ch = ((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2);
-            if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0) { // zzzz yyyy yyxx xxxx (0x800 to 0xffff)
-                fCurrentChunk = saveChunk;
-                fCurrentIndex = saveIndex;
-                fCurrentOffset = saveOffset;
-                fMostRecentData = saveChunk.toByteArray();
-                fMostRecentByte = b0;
-                return -1;
-            }
-            loadNextByte();
-            return ch;
-        }
-        // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-        fCurrentChunk = saveChunk;
-        fCurrentIndex = saveIndex;
-        fCurrentOffset = saveOffset;
-        fMostRecentData = saveChunk.toByteArray();
-        fMostRecentByte = b0;
-        return -1;
-    }
-    public int scanName(char fastcheck) throws Exception {
-        int b0 = fMostRecentByte;
-        int ch;
-        if (b0 < 0x80) {
-            if (XMLCharacterProperties.fgAsciiInitialNameChar[b0] == 0) {
-                if (b0 == 0 && atEOF(fCurrentOffset + 1)) {
-                    return changeReaders().scanName(fastcheck);
-                }
-                return -1;
-            }
-            ch = b0;
-        } else {
-            //
-            // REVISIT - optimize this with in-buffer lookahead.
-            //
-            UTF8DataChunk saveChunk = fCurrentChunk;
-            int saveIndex = fCurrentIndex;
-            int saveOffset = fCurrentOffset;
-            if (!fCalledCharPropInit) {
-                XMLCharacterProperties.initCharFlags();
-                fCalledCharPropInit = true;
-            }
-            int b1;
-            if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                b1 = loadNextByte();
-            } else {
-                fCurrentOffset++;
-                if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                    fCurrentIndex++;
-                    try {
-                        b1 = fMostRecentData[fCurrentIndex] & 0xFF;
-                    } catch (ArrayIndexOutOfBoundsException ex) {
-                        b1 = slowLoadNextByte();
-                    }
-                } else {
-                    if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                        b1 = slowLoadNextByte();
-                    else
-                        b1 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                }
-            }
-            if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx
-                ch = ((0x1f & b0)<<6) + (0x3f & b1);
-                if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0) { // yyy yyxx xxxx (0x80 to 0x7ff)
-                    fCurrentChunk = saveChunk;
-                    fCurrentIndex = saveIndex;
-                    fCurrentOffset = saveOffset;
-                    fMostRecentData = saveChunk.toByteArray();
-                    fMostRecentByte = b0;
-                    return -1;
-                }
-            } else {
-                int b2;
-                if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                    b2 = loadNextByte();
-                } else {
-                    fCurrentOffset++;
-                    if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                        fCurrentIndex++;
-                        try {
-                            b2 = fMostRecentData[fCurrentIndex] & 0xFF;
-                        } catch (ArrayIndexOutOfBoundsException ex) {
-                            b2 = slowLoadNextByte();
-                        }
-                    } else {
-                        if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                            b2 = slowLoadNextByte();
-                        else
-                            b2 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                    }
-                }
-                if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-                    // if ((ch >= 0xD800 && ch <= 0xDFFF) || ch >= 0xFFFE)
-                    if ((b0 == 0xED && b1 >= 0xA0) || (b0 == 0xEF && b1 == 0xBF && b2 >= 0xBE)) {
-                        fCurrentChunk = saveChunk;
-                        fCurrentIndex = saveIndex;
-                        fCurrentOffset = saveOffset;
-                        fMostRecentData = saveChunk.toByteArray();
-                        fMostRecentByte = b0;
-                        return -1;
-                    }
-                    ch = ((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2);
-                    if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0) { // zzzz yyyy yyxx xxxx (0x800 to 0xffff)
-                        fCurrentChunk = saveChunk;
-                        fCurrentIndex = saveIndex;
-                        fCurrentOffset = saveOffset;
-                        fMostRecentData = saveChunk.toByteArray();
-                        fMostRecentByte = b0;
-                        return -1;
-                    }
-                } else { // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-                    fCurrentChunk = saveChunk;
-                    fCurrentIndex = saveIndex;
-                    fCurrentOffset = saveOffset;
-                    fMostRecentData = saveChunk.toByteArray();
-                    fMostRecentByte = b0;
-                    return -1;
-                }
-            }
-        }
-        fCharacterCounter++;
-        if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-            b0 = loadNextByte();
-        } else {
-            fCurrentOffset++;
-            if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                fCurrentIndex++;
-                try {
-                    b0 = fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                } catch (ArrayIndexOutOfBoundsException ex) {
-                    b0 = slowLoadNextByte();
-                }
-            } else {
-                if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                    b0 = slowLoadNextByte();
-                else
-                    b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-            }
-        }
-        return scanMatchingName(ch, b0, fastcheck);
-    }
-    private int scanMatchingName(int ch, int b0, int fastcheck) throws Exception {
-        SymbolCache cache = fStringPool.getSymbolCache();
-        int[][] cacheLines = cache.fCacheLines;
-        char[] symbolChars = cache.fSymbolChars;
-        boolean lengthOfOne = fastcheck == fMostRecentByte;
-        int startOffset = cache.fSymbolCharsOffset;
-        int entry = 0;
-        int[] entries = cacheLines[entry];
-        int offset = 1 + ((entries[0] - 1) * SymbolCache.CACHE_RECORD_SIZE);
-        int totalMisses = 0;
-        if (lengthOfOne) {
-            while (offset > 0) {
-                if (entries[offset + SymbolCache.CHAR_OFFSET] == ch) {
-                    if (entries[offset + SymbolCache.INDEX_OFFSET] != -1) {
-                        int symbolIndex = entries[offset + SymbolCache.INDEX_OFFSET];
-                        if (totalMisses > 3)
-                            fStringPool.updateCacheLine(symbolIndex, totalMisses, 1);
-                        return symbolIndex;
-                    }
-                    break;
-                }
-                offset -= SymbolCache.CACHE_RECORD_SIZE;
-                totalMisses++;
-            }
-            try {
-                symbolChars[cache.fSymbolCharsOffset] = (char)ch;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                symbolChars = new char[cache.fSymbolCharsOffset * 2];
-                System.arraycopy(cache.fSymbolChars, 0, symbolChars, 0, cache.fSymbolCharsOffset);
-                cache.fSymbolChars = symbolChars;
-                symbolChars[cache.fSymbolCharsOffset] = (char)ch;
-            }
-            cache.fSymbolCharsOffset++;
-            if (offset < 0) {
-                offset = 1 + (entries[0] * SymbolCache.CACHE_RECORD_SIZE);
-                entries[0]++;
-                try {
-                    entries[offset + SymbolCache.CHAR_OFFSET] = ch;
-                } catch (ArrayIndexOutOfBoundsException ex) {
-                    int newSize = 1 + ((offset - 1) * 2);
-                    entries = new int[newSize];
-                    System.arraycopy(cacheLines[entry], 0, entries, 0, offset);
-                    cacheLines[entry] = entries;
-                    entries[offset + SymbolCache.CHAR_OFFSET] = ch;
-                }
-                entries[offset + SymbolCache.NEXT_OFFSET] = -1;
-            }
-            int result = fStringPool.createNonMatchingSymbol(startOffset, entry, entries, offset);
-            return result;
-        }
-        try {
-            symbolChars[cache.fSymbolCharsOffset] = (char)ch;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            symbolChars = new char[cache.fSymbolCharsOffset * 2];
-            System.arraycopy(cache.fSymbolChars, 0, symbolChars, 0, cache.fSymbolCharsOffset);
-            cache.fSymbolChars = symbolChars;
-            symbolChars[cache.fSymbolCharsOffset] = (char)ch;
-        }
-        cache.fSymbolCharsOffset++;
-        int depth = 1;
-        while (true) {
-            if (offset < 0)
-                break;
-            if (entries[offset + SymbolCache.CHAR_OFFSET] != ch) {
-                offset -= SymbolCache.CACHE_RECORD_SIZE;
-                totalMisses++;
-                continue;
-            }
-            if (b0 >= 0x80) {
-                ch = getMultiByteSymbolChar(b0);
-                b0 = fMostRecentByte;
-            } else if (b0 == fastcheck || XMLCharacterProperties.fgAsciiNameChar[b0] == 0) {
-                ch = -1;
-            } else {
-                ch = b0;
-                fCharacterCounter++;
-                if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                    b0 = loadNextByte();
-                } else {
-                    fCurrentOffset++;
-                    if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                        fCurrentIndex++;
-                        try {
-                            b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        } catch (ArrayIndexOutOfBoundsException ex) {
-                            b0 = slowLoadNextByte();
-                        }
-                    } else {
-                        if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                            b0 = slowLoadNextByte();
-                        else
-                            b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                    }
-                }
-            }
-            if (ch == -1) {
-                if (entries[offset + SymbolCache.INDEX_OFFSET] == -1) {
-                    return fStringPool.createNonMatchingSymbol(startOffset, entry, entries, offset);
-                }
-                cache.fSymbolCharsOffset = startOffset;
-                int symbolIndex = entries[offset + SymbolCache.INDEX_OFFSET];
-                if (totalMisses > (depth * 3))
-                    fStringPool.updateCacheLine(symbolIndex, totalMisses, depth);
-                return symbolIndex;
-            }
-            try {
-                symbolChars[cache.fSymbolCharsOffset] = (char)ch;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                symbolChars = new char[cache.fSymbolCharsOffset * 2];
-                System.arraycopy(cache.fSymbolChars, 0, symbolChars, 0, cache.fSymbolCharsOffset);
-                cache.fSymbolChars = symbolChars;
-                symbolChars[cache.fSymbolCharsOffset] = (char)ch;
-            }
-            cache.fSymbolCharsOffset++;
-            entry = entries[offset + SymbolCache.NEXT_OFFSET];
-            try {
-                entries = cacheLines[entry];
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                if (entry == -1) {
-                    entry = cache.fCacheLineCount++;
-                    entries[offset + SymbolCache.NEXT_OFFSET] = entry;
-                    entries = new int[1+(SymbolCache.INITIAL_CACHE_RECORD_COUNT*SymbolCache.CACHE_RECORD_SIZE)];
-                    try {
-                        cacheLines[entry] = entries;
-                    } catch (ArrayIndexOutOfBoundsException ex2) {
-                        cacheLines = new int[entry * 2][];
-                        System.arraycopy(cache.fCacheLines, 0, cacheLines, 0, entry);
-                        cache.fCacheLines = cacheLines;
-                        cacheLines[entry] = entries;
-                    }
-                } else {
-                    entries = cacheLines[entry];
-                    throw new RuntimeException("RDR001 untested"); // REVISIT
-                }
-            }
-            offset = 1 + ((entries[0] - 1) * SymbolCache.CACHE_RECORD_SIZE);
-            depth++;
-        }
-        if (offset < 0)
-            offset = 1 + (entries[0] * SymbolCache.CACHE_RECORD_SIZE);
-        while (true) {
-            entries[0]++;
-            try {
-                entries[offset + SymbolCache.CHAR_OFFSET] = ch;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                int newSize = 1 + ((offset - 1) * 2);
-                entries = new int[newSize];
-                System.arraycopy(cacheLines[entry], 0, entries, 0, offset);
-                cacheLines[entry] = entries;
-                entries[offset + SymbolCache.CHAR_OFFSET] = ch;
-            }
-            if (b0 >= 0x80) {
-                ch = getMultiByteSymbolChar(b0);
-                b0 = fMostRecentByte;
-            } else if (b0 == fastcheck || XMLCharacterProperties.fgAsciiNameChar[b0] == 0) {
-                ch = -1;
-            } else {
-                ch = b0;
-                fCharacterCounter++;
-                if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                    b0 = loadNextByte();
-                } else {
-                    fCurrentOffset++;
-                    if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                        fCurrentIndex++;
-                        try {
-                            b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        } catch (ArrayIndexOutOfBoundsException ex) {
-                            b0 = slowLoadNextByte();
-                        }
-                    } else {
-                        if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                            b0 = slowLoadNextByte();
-                        else
-                            b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                    }
-                }
-            }
-            if (ch == -1) {
-                entries[offset + SymbolCache.NEXT_OFFSET] = -1;
-                break;
-            }
-            entry = cache.fCacheLineCount++;
-            entries[offset + SymbolCache.INDEX_OFFSET] = -1;
-            entries[offset + SymbolCache.NEXT_OFFSET] = entry;
-            entries = new int[1+(SymbolCache.INITIAL_CACHE_RECORD_COUNT*SymbolCache.CACHE_RECORD_SIZE)];
-            try {
-                cacheLines[entry] = entries;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                cacheLines = new int[entry * 2][];
-                System.arraycopy(cache.fCacheLines, 0, cacheLines, 0, entry);
-                cache.fCacheLines = cacheLines;
-                cacheLines[entry] = entries;
-            }
-            offset = 1;
-            try {
-                symbolChars[cache.fSymbolCharsOffset] = (char)ch;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                symbolChars = new char[cache.fSymbolCharsOffset * 2];
-                System.arraycopy(cache.fSymbolChars, 0, symbolChars, 0, cache.fSymbolCharsOffset);
-                cache.fSymbolChars = symbolChars;
-                symbolChars[cache.fSymbolCharsOffset] = (char)ch;
-            }
-            cache.fSymbolCharsOffset++;
-        }
-
-        int result = fStringPool.createNonMatchingSymbol(startOffset, entry, entries, offset);
-        return result;
-    }
-    //
-    // [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
-    //
-    private int recognizeMarkup(int b0, QName element) throws Exception {
-        switch (b0) {
-        case 0:
-            return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-        case '?':
-            fCharacterCounter++;
-            loadNextByte();
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_PI;
-        case '!':
-            fCharacterCounter++;
-            b0 = loadNextByte();
-            if (b0 == 0) {
-                fCharacterCounter--;
-                fCurrentOffset--;
-                return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-            }
-            if (b0 == '-') {
-                fCharacterCounter++;
-                b0 = loadNextByte();
-                if (b0 == 0) {
-                    fCharacterCounter -= 2;
-                    fCurrentOffset -= 2;
-                    return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-                }
-                if (b0 == '-') {
-                    fCharacterCounter++;
-                    b0 = loadNextByte();
-                    return XMLEntityHandler.CONTENT_RESULT_START_OF_COMMENT;
-                }
-                break;
-            }
-            if (b0 == '[') {
-                for (int i = 0; i < 6; i++) {
-                    fCharacterCounter++;
-                    b0 = loadNextByte();
-                    if (b0 == 0) {
-                        fCharacterCounter -= (2 + i);
-                        fCurrentOffset -= (2 + i);
-                        return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
-                    }
-                    if (b0 != cdata_string[i]) {
-                        return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
-                    }
-                }
-                fCharacterCounter++;
-                loadNextByte();
-                return XMLEntityHandler.CONTENT_RESULT_START_OF_CDSECT;
-            }
-            break;
-        case '/':
-            fCharacterCounter++;
-            if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                b0 = loadNextByte();
-            } else {
-                fCurrentOffset++;
-                if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                    fCurrentIndex++;
-                    try {
-                        b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                    } catch (ArrayIndexOutOfBoundsException ex) {
-                        b0 = slowLoadNextByte();
-                    }
-                } else {
-                    if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                        b0 = slowLoadNextByte();
-                    else
-                        b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                }
-            }
-            int expectedName = element.rawname;
-            fStringPool.getCharArrayRange(expectedName, fCharArrayRange);
-            char[] expected = fCharArrayRange.chars;
-            int offset = fCharArrayRange.offset;
-            int len = fCharArrayRange.length;
-            //
-            // DEFECT !! - needs UTF8 multibyte support...
-            //
-            if (b0 == expected[offset++]) {
-                UTF8DataChunk savedChunk = fCurrentChunk;
-                int savedIndex = fCurrentIndex;
-                int savedOffset = fCurrentOffset;
-                for (int i = 1; i < len; i++) {
-                    if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                        b0 = loadNextByte();
-                    } else {
-                        fCurrentOffset++;
-                        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                            fCurrentIndex++;
-                            try {
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                            } catch (ArrayIndexOutOfBoundsException ex) {
-                                b0 = slowLoadNextByte();
-                            }
-                        } else {
-                            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                b0 = slowLoadNextByte();
-                            else
-                                b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        }
-                    }
-                    //
-                    // DEFECT !! - needs UTF8 multibyte support...
-                    //
-                    if (b0 != expected[offset++]) {
-                        fCurrentChunk = savedChunk;
-                        fCurrentIndex = savedIndex;
-                        fCurrentOffset = savedOffset;
-                        fMostRecentData = fCurrentChunk.toByteArray();
-                        fMostRecentByte = fMostRecentData[savedIndex] & 0xFF;
-                        return XMLEntityHandler.CONTENT_RESULT_START_OF_ETAG;
-                    }
-                }
-                fCharacterCounter += len; // REVISIT - double check this...
-                fCharacterCounter++;
-                if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                    b0 = loadNextByte();
-                } else {
-                    fCurrentOffset++;
-                    if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                        fCurrentIndex++;
-                        try {
-                            b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        } catch (ArrayIndexOutOfBoundsException ex) {
-                            b0 = slowLoadNextByte();
-                        }
-                    } else {
-                        if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                            b0 = slowLoadNextByte();
-                        else
-                            b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                    }
-                }
-                if (b0 == '>') {
-                    fCharacterCounter++;
-                    if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                        loadNextByte();
-                    } else {
-                        fCurrentOffset++;
-                        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                            fCurrentIndex++;
-                            try {
-                                fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                            } catch (ArrayIndexOutOfBoundsException ex) {
-                                slowLoadNextByte();
-                            }
-                        } else {
-                            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                slowLoadNextByte();
-                            else
-                                fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                        }
-                    }
-                    return XMLEntityHandler.CONTENT_RESULT_MATCHING_ETAG;
-                }
-                while (b0 == 0x20 || b0 == 0x09 || b0 == 0x0A || b0 == 0x0D) {
-                    if (b0 == 0x0A) {
-                        fLinefeedCounter++;
-                        fCharacterCounter = 1;
-                        b0 = loadNextByte();
-                    } else if (b0 == 0x0D) {
-                        fCarriageReturnCounter++;
-                        fCharacterCounter = 1;
-                        b0 = loadNextByte();
-                        if (b0 == 0x0A) {
-                            fLinefeedCounter++;
-                            b0 = loadNextByte();
-                        }
-                    } else {
-                        fCharacterCounter++;
-                        b0 = loadNextByte();
-                    }
-                    if (b0 == '>') {
-                        fCharacterCounter++;
-                        if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                            loadNextByte();
-                        } else {
-                            fCurrentOffset++;
-                            if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                                fCurrentIndex++;
-                                try {
-                                    fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                                } catch (ArrayIndexOutOfBoundsException ex) {
-                                    slowLoadNextByte();
-                                }
-                            } else {
-                                if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                    slowLoadNextByte();
-                                else
-                                    fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
-                            }
-                        }
-                        return XMLEntityHandler.CONTENT_RESULT_MATCHING_ETAG;
-                    }
-                }
-                fCurrentChunk = savedChunk;
-                fCurrentIndex = savedIndex;
-                fCurrentOffset = savedOffset;
-                fMostRecentData = fCurrentChunk.toByteArray();
-                fMostRecentByte = fMostRecentData[savedIndex] & 0xFF;
-            }
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ETAG;
-        default:
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ELEMENT;
-        }
-        return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
-    }
-    private int recognizeReference(int ch) throws Exception {
-        if (ch == 0) {
-            return XMLEntityHandler.CONTENT_RESULT_REFERENCE_END_OF_INPUT;
-        }
-        //
-        // [67] Reference ::= EntityRef | CharRef
-        // [68] EntityRef ::= '&' Name ';'
-        // [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
-        //
-        if (ch == '#') {
-            fCharacterCounter++;
-            loadNextByte();
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_CHARREF;
-        } else {
-            return XMLEntityHandler.CONTENT_RESULT_START_OF_ENTITYREF;
-        }
-    }
-    public int scanContent(QName element) throws Exception {
-        if (fCallClearPreviousChunk && fCurrentChunk.clearPreviousChunk())
-            fCallClearPreviousChunk = false;
-        fCharDataLength = 0;
-        int charDataOffset = fCurrentOffset;
-        int ch = fMostRecentByte;
-        if (ch < 0x80) {
-            switch (XMLCharacterProperties.fgAsciiWSCharData[ch]) {
-            case 0:
-                if (fSendCharDataAsCharArray) {
-                    try {
-                        fCharacters[fCharDataLength] = (char)ch;
-                        fCharDataLength++;
-                    } catch (ArrayIndexOutOfBoundsException ex) {
-                        slowAppendCharData(ch);
-                    }
-                }
-                fCharacterCounter++;
-                if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                    ch = loadNextByte();
-                } else {
-                    fCurrentOffset++;
-                    if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                        fCurrentIndex++;
-                        try {
-                            ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        } catch (ArrayIndexOutOfBoundsException ex) {
-                            ch = slowLoadNextByte();
-                        }
-                    } else {
-                        if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                            ch = slowLoadNextByte();
-                        else
-                            ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                    }
-                }
-                break;
-            case 1: // '<'
-                fCharacterCounter++;
-                if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                    ch = loadNextByte();
-                } else {
-                    fCurrentOffset++;
-                    if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                        fCurrentIndex++;
-                        try {
-                            ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        } catch (ArrayIndexOutOfBoundsException ex) {
-                            ch = slowLoadNextByte();
-                        }
-                    } else {
-                        if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                            ch = slowLoadNextByte();
-                        else
-                            ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                    }
-                }
-                if (!fInCDSect) {
-                    return recognizeMarkup(ch, element);
-                }
-                if (fSendCharDataAsCharArray)
-                    appendCharData('<');
-                break;
-            case 2: // '&'
-                fCharacterCounter++;
-                ch = loadNextByte();
-                if (!fInCDSect) {
-                    return recognizeReference(ch);
-                }
-                if (fSendCharDataAsCharArray)
-                    appendCharData('&');
-                break;
-            case 3: // ']'
-                fCharacterCounter++;
-                ch = loadNextByte();
-                if (ch != ']') {
-                    if (fSendCharDataAsCharArray)
-                        appendCharData(']');
-                    break;
-                }
-                if (fCurrentIndex + 1 == UTF8DataChunk.CHUNK_SIZE) {
-                    UTF8DataChunk saveChunk = fCurrentChunk;
-                    int saveIndex = fCurrentIndex;
-                    int saveOffset = fCurrentOffset;
-                    if (loadNextByte() != '>') {
-                        fCurrentChunk = saveChunk;
-                        fCurrentIndex = saveIndex;
-                        fCurrentOffset = saveOffset;
-                        fMostRecentData = fCurrentChunk.toByteArray();
-                        fMostRecentByte = ']';
-                        if (fSendCharDataAsCharArray)
-                            appendCharData(']');
-                        break;
-                    }
-                } else {
-                    if (fMostRecentData[fCurrentIndex + 1] != '>') {
-                        if (fSendCharDataAsCharArray)
-                            appendCharData(']');
-                        break;
-                    }
-                    fCurrentIndex++;
-                    fCurrentOffset++;
-                }
-                loadNextByte();
-                fCharacterCounter += 2;
-                return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-            case 4: // invalid char
-                if (ch == 0 && atEOF(fCurrentOffset + 1)) {
-                    changeReaders();
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR; // REVISIT - not quite...
-                }
-                return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-            case 5:
-                do {
-                    if (ch == 0x0A) {
-                        fLinefeedCounter++;
-                        fCharacterCounter = 1;
-                    } else if (ch == 0x0D) {
-                        fCarriageReturnCounter++;
-                        fCharacterCounter = 1;
-                        if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                            ch = loadNextByte();
-                        } else {
-                            fCurrentOffset++;
-                            if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                                fCurrentIndex++;
-                                try {
-                                    ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                                } catch (ArrayIndexOutOfBoundsException ex) {
-                                    ch = slowLoadNextByte();
-                                }
-                            } else {
-                                if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                    ch = slowLoadNextByte();
-                                else
-                                    ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                            }
-                        }
-                        if (ch != 0x0A) {
-                            if (fSendCharDataAsCharArray)
-                                appendCharData(0x0A);
-                            if (ch == 0x20 || ch == 0x09 || ch == 0x0D)
-                                continue;
-                            break;
-                        }
-                        fLinefeedCounter++;
-                    } else {
-                        fCharacterCounter++;
-                    }
-                    if (fSendCharDataAsCharArray) {
-                        try {
-                            fCharacters[fCharDataLength] = (char)ch;
-                            fCharDataLength++;
-                        } catch (ArrayIndexOutOfBoundsException ex) {
-                            slowAppendCharData(ch);
-                        }
-                    }
-                    if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                        ch = loadNextByte();
-                    } else {
-                        fCurrentOffset++;
-                        if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                            fCurrentIndex++;
-                            try {
-                                ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                            } catch (ArrayIndexOutOfBoundsException ex) {
-                                ch = slowLoadNextByte();
-                            }
-                        } else {
-                            if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                ch = slowLoadNextByte();
-                            else
-                                ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                        }
-                    }
-                } while (ch == 0x20 || ch == 0x09 || ch == 0x0A || ch == 0x0D);
-                if (ch < 0x80) {
-                    switch (XMLCharacterProperties.fgAsciiCharData[ch]) {
-                    case 0:
-                        if (fSendCharDataAsCharArray)
-                            appendCharData(ch);
-                        fCharacterCounter++;
-                        ch = loadNextByte();
-                        break;
-                    case 1: // '<'
-                        if (!fInCDSect) {
-                            if (fSendCharDataAsCharArray) {
-                                fCharDataHandler.processWhitespace(fCharacters, 0, fCharDataLength);
-                            } else {
-                                int stringIndex = addString(charDataOffset, fCurrentOffset - charDataOffset);
-                                fCharDataHandler.processWhitespace(stringIndex);
-                            }
-                            fCharacterCounter++;
-                            if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                                ch = loadNextByte();
-                            } else {
-                                fCurrentOffset++;
-                                if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                                    fCurrentIndex++;
-                                    try {
-                                        ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                                    } catch (ArrayIndexOutOfBoundsException ex) {
-                                        ch = slowLoadNextByte();
-                                    }
-                                } else {
-                                    if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                        ch = slowLoadNextByte();
-                                    else
-                                        ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                                }
-                            }
-                            return recognizeMarkup(ch, element);
-                        }
-                        if (fSendCharDataAsCharArray)
-                            appendCharData('<');
-                        fCharacterCounter++;
-                        ch = loadNextByte();
-                        break;
-                    case 2: // '&'
-                        if (!fInCDSect) {
-                            whitespace(charDataOffset, fCurrentOffset);
-                            fCharacterCounter++;
-                            ch = loadNextByte();
-                            return recognizeReference(ch);
-                        }
-                        if (fSendCharDataAsCharArray)
-                            appendCharData('&');
-                        fCharacterCounter++;
-                        ch = loadNextByte();
-                        break;
-                    case 3: // ']'
-                        int endOffset = fCurrentOffset;
-                        ch = loadNextByte();
-                        if (ch != ']') {
-                            fCharacterCounter++;
-                            if (fSendCharDataAsCharArray)
-                                appendCharData(']');
-                            break;
-                        }
-                        if (fCurrentIndex + 1 == UTF8DataChunk.CHUNK_SIZE) {
-                            UTF8DataChunk saveChunk = fCurrentChunk;
-                            int saveIndex = fCurrentIndex;
-                            int saveOffset = fCurrentOffset;
-                            if (loadNextByte() != '>') {
-                                fCurrentChunk = saveChunk;
-                                fCurrentIndex = saveIndex;
-                                fCurrentOffset = saveOffset;
-                                fMostRecentData = fCurrentChunk.toByteArray();
-                                fMostRecentByte = ']';
-                                fCharacterCounter++;
-                                if (fSendCharDataAsCharArray)
-                                    appendCharData(']');
-                                break;
-                            }
-                        } else {
-                            if (fMostRecentData[fCurrentIndex + 1] != '>') {
-                                fCharacterCounter++;
-                                if (fSendCharDataAsCharArray)
-                                    appendCharData(']');
-                                break;
-                            }
-                            fCurrentIndex++;
-                            fCurrentOffset++;
-                        }
-                        loadNextByte();
-                        whitespace(charDataOffset, endOffset);
-                        fCharacterCounter += 3;
-                        return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-                    case 4: // invalid char
-                        whitespace(charDataOffset, fCurrentOffset);
-                        if (ch == 0 && atEOF(fCurrentOffset + 1)) {
-                            changeReaders();
-                            return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR; // REVISIT - not quite...
-                        }
-                        return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                    }
-                } else {
-                    if (fSendCharDataAsCharArray) {
-                        if (!copyMultiByteCharData(ch)) {
-                            whitespace(charDataOffset, fCurrentOffset);
-                            return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                        }
-                    } else if (!skipMultiByteCharData(ch)) {
-                        whitespace(charDataOffset, fCurrentOffset);
-                        return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                    }
-                }
-                break;
-            }
-        } else {
-            if (fSendCharDataAsCharArray) {
-                if (!copyMultiByteCharData(ch)) {
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-            } else {
-                if (!skipMultiByteCharData(ch)) {
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-            }
-        }
-        if (fSendCharDataAsCharArray)
-            ch = copyAsciiCharData();
-        else
-            ch = skipAsciiCharData();
-        while (true) {
-            if (ch < 0x80) {
-                switch (XMLCharacterProperties.fgAsciiCharData[ch]) {
-                case 0:
-                    if (fSendCharDataAsCharArray)
-                        appendCharData(ch);
-                    fCharacterCounter++;
-                    ch = loadNextByte();
-                    break;
-                case 1: // '<'
-                    if (!fInCDSect) {
-                        if (fSendCharDataAsCharArray) {
-                            fCharDataHandler.processCharacters(fCharacters, 0, fCharDataLength);
-                        } else {
-                            int stringIndex = addString(charDataOffset, fCurrentOffset - charDataOffset);
-                            fCharDataHandler.processCharacters(stringIndex);
-                        }
-                        fCharacterCounter++;
-                        if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
-                            ch = loadNextByte();
-                        } else {
-                            fCurrentOffset++;
-                            if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
-                                fCurrentIndex++;
-                                try {
-                                    ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                                } catch (ArrayIndexOutOfBoundsException ex) {
-                                    ch = slowLoadNextByte();
-                                }
-                            } else {
-                                if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
-                                    ch = slowLoadNextByte();
-                                else
-                                    ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
-                            }
-                        }
-                        return recognizeMarkup(ch, element);
-                    }
-                    if (fSendCharDataAsCharArray)
-                        appendCharData('<');
-                    fCharacterCounter++;
-                    ch = loadNextByte();
-                    break;
-                case 2: // '&'
-                    if (!fInCDSect) {
-                        characters(charDataOffset, fCurrentOffset);
-                        fCharacterCounter++;
-                        ch = loadNextByte();
-                        return recognizeReference(ch);
-                    }
-                    if (fSendCharDataAsCharArray)
-                        appendCharData('&');
-                    fCharacterCounter++;
-                    ch = loadNextByte();
-                    break;
-                case 3: // ']'
-                    int endOffset = fCurrentOffset;
-                    ch = loadNextByte();
-                    if (ch != ']') {
-                        fCharacterCounter++;
-                        if (fSendCharDataAsCharArray)
-                            appendCharData(']');
-                        break;
-                    }
-                    if (fCurrentIndex + 1 == UTF8DataChunk.CHUNK_SIZE) {
-                        UTF8DataChunk saveChunk = fCurrentChunk;
-                        int saveIndex = fCurrentIndex;
-                        int saveOffset = fCurrentOffset;
-                        if (loadNextByte() != '>') {
-                            fCurrentChunk = saveChunk;
-                            fCurrentIndex = saveIndex;
-                            fCurrentOffset = saveOffset;
-                            fMostRecentData = fCurrentChunk.toByteArray();
-                            fMostRecentByte = ']';
-                            fCharacterCounter++;
-                            if (fSendCharDataAsCharArray)
-                                appendCharData(']');
-                            break;
-                        }
-                    } else {
-                        if (fMostRecentData[fCurrentIndex + 1] != '>') {
-                            fCharacterCounter++;
-                            if (fSendCharDataAsCharArray)
-                                appendCharData(']');
-                            break;
-                        }
-                        fCurrentIndex++;
-                        fCurrentOffset++;
-                    }
-                    loadNextByte();
-                    characters(charDataOffset, endOffset);
-                    fCharacterCounter += 3;
-                    return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
-                case 4: // invalid char
-                    if (ch == 0x0A) {
-                        if (fSendCharDataAsCharArray)
-                            appendCharData(ch);
-                        fLinefeedCounter++;
-                        fCharacterCounter = 1;
-                        ch = loadNextByte();
-                        break;
-                    }
-                    if (ch == 0x0D) {
-                        if (fSendCharDataAsCharArray)
-                            appendCharData(0x0A);
-                        fCarriageReturnCounter++;
-                        fCharacterCounter = 1;
-                        ch = loadNextByte();
-                        if (ch == 0x0A) {
-                            fLinefeedCounter++;
-                            ch = loadNextByte();
-                        }
-                        break;
-                    }
-                    characters(charDataOffset, fCurrentOffset);
-                    if (ch == 0 && atEOF(fCurrentOffset + 1)) {
-                        changeReaders();
-                        return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR; // REVISIT - not quite...
-                    }
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-            } else {
-                if (fSendCharDataAsCharArray) {
-                    if (!copyMultiByteCharData(ch)) {
-                        characters(charDataOffset, fCurrentOffset);
-                        return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                    }
-                } else if (!skipMultiByteCharData(ch)) {
-                    characters(charDataOffset, fCurrentOffset);
-                    return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
-                }
-                ch = fMostRecentByte;
-            }
-        }
-    }
-    private boolean copyMultiByteCharData(int b0) throws Exception {
-        UTF8DataChunk saveChunk = fCurrentChunk;
-        int saveOffset = fCurrentOffset;
-        int saveIndex = fCurrentIndex;
-        int b1 = loadNextByte();
-        if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx (0x80 to 0x7ff)
-            int ch = ((0x1f & b0)<<6) + (0x3f & b1);
-            appendCharData(ch); // yyy yyxx xxxx (0x80 to 0x7ff)
-            loadNextByte();
-            return true;
-        }
-        int b2 = loadNextByte();
-        if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-            // ch = ((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2); // zzzz yyyy yyxx xxxx (0x800 to 0xffff)
-            // if ((ch >= 0xD800 && ch <= 0xDFFF) || ch >= 0xFFFE)
-            if ((b0 == 0xED && b1 >= 0xA0) || (b0 == 0xEF && b1 == 0xBF && b2 >= 0xBE)) {
-                fCurrentChunk = saveChunk;
-                fCurrentIndex = saveIndex;
-                fCurrentOffset = saveOffset;
-                fMostRecentData = saveChunk.toByteArray();
-                fMostRecentByte = b0;
-                return false;
-            }
-            int ch = ((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2);
-            appendCharData(ch); // zzzz yyyy yyxx xxxx (0x800 to 0xffff)
-            loadNextByte();
-            return true;
-        }
-
-        int b3 = loadNextByte();  // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-        // ch = ((0x0f & b0)<<18) + ((0x3f & b1)<<12) + ((0x3f & b2)<<6) + (0x3f & b3); // u uuuu zzzz yyyy yyxx xxxx (0x10000 to 0x1ffff)
-        // if (ch >= 0x110000)
-        if (( 0xf8 & b0 ) == 0xf0 ) {
-            if (b0 > 0xF4 || (b0 == 0xF4 && b1 >= 0x90)) {
-                fCurrentChunk = saveChunk;
-                fCurrentIndex = saveIndex;
-                fCurrentOffset = saveOffset;
-                fMostRecentData = saveChunk.toByteArray();
-                fMostRecentByte = b0;
-                return false;
-            }
-            int ch = ((0x0f & b0)<<18) + ((0x3f & b1)<<12) + ((0x3f & b2)<<6) + (0x3f & b3);
-            if (ch < 0x10000) {
-                appendCharData(ch);
-            } else {
-                appendCharData(((ch-0x00010000)>>10)+0xd800);
-                appendCharData(((ch-0x00010000)&0x3ff)+0xdc00);
-            }
-            loadNextByte();
-            return true;
-        } else {
-            fCurrentChunk = saveChunk;
-            fCurrentIndex = saveIndex;
-            fCurrentOffset = saveOffset;
-            fMostRecentData = saveChunk.toByteArray();
-            fMostRecentByte = b0;
-            return false;
-        }
-    }
-    private boolean skipMultiByteCharData(int b0) throws Exception {
-        UTF8DataChunk saveChunk = fCurrentChunk;
-        int saveOffset = fCurrentOffset;
-        int saveIndex = fCurrentIndex;
-        int b1 = loadNextByte();
-        if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx (0x80 to 0x7ff)
-            loadNextByte();
-            return true;
-        }
-        int b2 = loadNextByte();
-        if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-            // ch = ((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2); // zzzz yyyy yyxx xxxx (0x800 to 0xffff)
-            // if ((ch >= 0xD800 && ch <= 0xDFFF) || ch >= 0xFFFE)
-            if ((b0 == 0xED && b1 >= 0xA0) || (b0 == 0xEF && b1 == 0xBF && b2 >= 0xBE)) {
-                fCurrentChunk = saveChunk;
-                fCurrentIndex = saveIndex;
-                fCurrentOffset = saveOffset;
-                fMostRecentData = saveChunk.toByteArray();
-                fMostRecentByte = b0;
-                return false;
-            }
-            loadNextByte();
-            return true;
-        }
-        int b3 = loadNextByte();  // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-        // ch = ((0x0f & b0)<<18) + ((0x3f & b1)<<12) + ((0x3f & b2)<<6) + (0x3f & b3); // u uuuu zzzz yyyy yyxx xxxx (0x10000 to 0x1ffff)
-        // if (ch >= 0x110000)
-        if (b0 > 0xF4 || (b0 == 0xF4 && b1 >= 0x90)) {
-            fCurrentChunk = saveChunk;
-            fCurrentIndex = saveIndex;
-            fCurrentOffset = saveOffset;
-            fMostRecentData = saveChunk.toByteArray();
-            fMostRecentByte = b0;
-            return false;
-        }
-        loadNextByte();
-        return true;
-    }
-    private int copyAsciiCharData() throws Exception {
-        int srcIndex = fCurrentIndex;
-        int offset = fCurrentOffset - srcIndex;
-        byte[] data = fMostRecentData;
-        int dstIndex = fCharDataLength;
-        boolean skiplf = false;
-        while (true) {
-            int ch;
-            try {
-                ch = data[srcIndex] & 0xFF;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                offset += srcIndex;
-                slowLoadNextByte();
-                srcIndex = 0;
-                data = fMostRecentData;
-                ch = data[srcIndex] & 0xFF;
-            }
-            if (ch >= 0x80) {
-                fCurrentOffset = offset + srcIndex;
-                fCurrentIndex = srcIndex;
-                fMostRecentByte = ch;
-                return ch;
-            }
-            if (XMLCharacterProperties.fgAsciiCharData[ch] == 0) {
-                fCharacterCounter++;
-                skiplf = false;
-            } else if (ch == 0x0A) {
-                fLinefeedCounter++;
-                if (skiplf) {
-                    skiplf = false;
-                    srcIndex++;
-                    continue;
-                }
-                fCharacterCounter = 1;
-            } else if (ch == 0x0D) {
-                fCarriageReturnCounter++;
-                fCharacterCounter = 1;
-                skiplf = true;
-                ch = 0x0A;
-            } else {
-                fCurrentOffset = offset + srcIndex;
-                fCurrentIndex = srcIndex;
-                fMostRecentByte = ch;
-                return ch;
-            }
-            srcIndex++;
-            try {
-                fCharacters[fCharDataLength] = (char)ch;
-                fCharDataLength++;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                slowAppendCharData(ch);
-            }
-        }
-    }
-    private int skipAsciiCharData() throws Exception {
-        int srcIndex = fCurrentIndex;
-        int offset = fCurrentOffset - srcIndex;
-        byte[] data = fMostRecentData;
-        while (true) {
-            int ch;
-            try {
-                ch = data[srcIndex] & 0xFF;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                offset += srcIndex;
-                slowLoadNextByte();
-                srcIndex = 0;
-                data = fMostRecentData;
-                ch = data[srcIndex] & 0xFF;
-            }
-            if (ch >= 0x80) {
-                fCurrentOffset = offset + srcIndex;
-                fCurrentIndex = srcIndex;
-                fMostRecentByte = ch;
-                return ch;
-            }
-            if (XMLCharacterProperties.fgAsciiCharData[ch] == 0) {
-                fCharacterCounter++;
-            } else if (ch == 0x0A) {
-                fLinefeedCounter++;
-                fCharacterCounter = 1;
-            } else if (ch == 0x0D) {
-                fCarriageReturnCounter++;
-                fCharacterCounter = 1;
-            } else {
-                fCurrentOffset = offset + srcIndex;
-                fCurrentIndex = srcIndex;
-                fMostRecentByte = ch;
-                return ch;
-            }
-            srcIndex++;
-        }
-    }
-    private char[] fCharacters = new char[UTF8DataChunk.CHUNK_SIZE];
-    private int fCharDataLength = 0;
-    private void appendCharData(int ch) throws Exception {
-        try {
-            fCharacters[fCharDataLength] = (char)ch;
-            fCharDataLength++;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            slowAppendCharData(ch);
-        }
-    }
-    private void slowAppendCharData(int ch) throws Exception {
-        // flush the buffer...
-        characters(0, fCharDataLength); /* DEFECT !! whitespace this long is unlikely, but possible */
-        fCharDataLength = 0;
-        fCharacters[fCharDataLength++] = (char)ch;
-    }
-    private void characters(int offset, int endOffset) throws Exception {
-        //
-        // REVISIT - need more up front bounds checking code of params...
-        //
-        if (!fSendCharDataAsCharArray) {
-            int stringIndex = addString(offset, endOffset - offset);
-            fCharDataHandler.processCharacters(stringIndex);
-            return;
-        }
-        fCharDataHandler.processCharacters(fCharacters, 0, fCharDataLength);
-    }
-    private void whitespace(int offset, int endOffset) throws Exception {
-        //
-        // REVISIT - need more up front bounds checking code of params...
-        //
-        if (!fSendCharDataAsCharArray) {
-            int stringIndex = addString(offset, endOffset - offset);
-            fCharDataHandler.processWhitespace(stringIndex);
-            return;
-        }
-        fCharDataHandler.processWhitespace(fCharacters, 0, fCharDataLength);
-    }
-    //
-    //
-    //
-    private static final char[] cdata_string = { 'C','D','A','T','A','['};
-    private StringPool.CharArrayRange fCharArrayRange = null;
-    private InputStream fInputStream = null;
-    private StringPool fStringPool = null;
-    private UTF8DataChunk fCurrentChunk = null;
-    private int fCurrentIndex = 0;
-    private byte[] fMostRecentData = null;
-    private int fMostRecentByte = 0;
-    private int fLength = 0;
-    private boolean fCalledCharPropInit = false;
-    private boolean fCallClearPreviousChunk = true;
-    //
-    //
-    //
-    private int fillCurrentChunk() throws Exception {
-        byte[] buf = fCurrentChunk.toByteArray();
-        if (fInputStream == null) {
-            if (buf == null)
-                buf = new byte[1];
-            buf[0] = 0;
-            fMostRecentData = buf;
-            fCurrentIndex = 0;
-            fCurrentChunk.setByteArray(fMostRecentData);
-            return(fMostRecentByte = fMostRecentData[0] & 0xFF);
-        }
-        if (buf == null)
-            buf = new byte[UTF8DataChunk.CHUNK_SIZE];
-        int offset = 0;
-        int capacity = UTF8DataChunk.CHUNK_SIZE;
-        int result = 0;
-        do {
-            try {
-                result = fInputStream.read(buf, offset, capacity);
-            } catch (java.io.IOException ex) {
-                result = -1;
-            }
-            if (result == -1) {
-                //
-                // We have reached the end of the stream.
-                //
-                fInputStream.close();
-                fInputStream = null;
-                try {
-                    buf[offset] = 0;
-                } catch (ArrayIndexOutOfBoundsException ex) {
-                }
-                break;
-            }
-            if (result > 0) {
-                offset += result;
-                capacity -= result;
-            }
-        } while (capacity > 0);
-        fMostRecentData = buf;
-        fLength += offset;
-        fCurrentIndex = 0;
-        fCurrentChunk.setByteArray(fMostRecentData);
-        return(fMostRecentByte = fMostRecentData[0] & 0xFF);
-    }
-}
diff --git a/src/org/apache/xerces/readers/UTF8Recognizer.java b/src/org/apache/xerces/readers/UTF8Recognizer.java
deleted file mode 100644
index 6083cd4..0000000
--- a/src/org/apache/xerces/readers/UTF8Recognizer.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.ChunkyByteArray;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringPool;
-
-import java.io.InputStreamReader;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-
-/**
- *
- * @version
- */
-final class UTF8Recognizer extends XMLDeclRecognizer {
-    private byte[] fUTF8BOM = {(byte)0xEF, (byte)0xBB, (byte)0xBF};
-    //
-    //
-    //
-    public XMLEntityHandler.EntityReader recognize(XMLEntityReaderFactory readerFactory,
-                                                   XMLEntityHandler entityHandler,
-                                                   XMLErrorReporter errorReporter,
-                                                   boolean sendCharDataAsCharArray,
-                                                   StringPool stringPool,
-                                                   ChunkyByteArray data,
-                                                   boolean xmlDecl,
-                                                   boolean allowJavaEncodingName) throws Exception {
-        XMLEntityHandler.EntityReader reader = null;
-
-        //check to see if there is a UTF8 BOM, if see one, skip past it.
-        boolean seeBOM = false;
-        byte bom0 = data.byteAt(0);
-        if (bom0 == fUTF8BOM[0]) {
-            byte bom1 = data.byteAt(1);
-            if (bom1 == fUTF8BOM[1]) {
-                byte bom2 = data.byteAt(2);
-                if (bom2 == fUTF8BOM[2]) {
-                    seeBOM = true;
-                }
-            }
-        }
-        if (seeBOM) {
-            // it will have the same content anyway.
-            data.read(fUTF8BOM, 0, 3);
-        }
-
-        byte b0 = data.byteAt(0);
-        boolean debug = false;
-
-        if (b0 == '<') {
-            int b1 = data.byteAt(1);
-            if (b1 == '?') {
-                if (data.byteAt(2) == 'x' && data.byteAt(3) == 'm' && data.byteAt(4) == 'l') {
-                    int b5 = data.byteAt(5);
-                    if (b5 == 0x20 || b5 == 0x09 || b5 == 0x0a || b5 == 0x0d) {
-                        XMLEntityHandler.EntityReader declReader = new XMLDeclReader(entityHandler, errorReporter, sendCharDataAsCharArray, data, stringPool);
-                        int encoding = prescanXMLDeclOrTextDecl(declReader, xmlDecl);
-                        if (encoding != -1) {
-                            String encname = stringPool.orphanString(encoding);
-                            String enc = encname.toUpperCase();
-                            if ("ISO-10646-UCS-2".equals(enc)) throw new UnsupportedEncodingException(encname);
-                            if ("ISO-10646-UCS-4".equals(enc)) throw new UnsupportedEncodingException(encname);
-                            if ("UTF-16".equals(enc)) throw new UnsupportedEncodingException(encname);
-
-                            String javaencname = MIME2Java.convert(enc);
-                            if (null == javaencname) {
-                                // Not supported
-                                if (allowJavaEncodingName) {
-                                    javaencname = encname;
-                                } else {
-                                    throw new UnsupportedEncodingException(encname);
-                                }
-                            }
-                            try {
-                                data.rewind();
-                                if ("UTF-8".equalsIgnoreCase(javaencname) || "UTF8".equalsIgnoreCase(javaencname)) {
-                                    reader = readerFactory.createUTF8Reader(entityHandler, errorReporter, sendCharDataAsCharArray, data, stringPool);
-                                } else {
-                                    reader = readerFactory.createCharReader(entityHandler, errorReporter, sendCharDataAsCharArray,
-                                                                            new InputStreamReader(data, javaencname), stringPool);
-                                }
-                            } catch (UnsupportedEncodingException e) {
-                                throw new UnsupportedEncodingException(encname);
-                            } catch (Exception e) {
-                                if( debug == true )
-                                   e.printStackTrace();            // Internal Error
-                            }
-                        } else {
-                            data.rewind();
-                            reader = readerFactory.createUTF8Reader(entityHandler, errorReporter, sendCharDataAsCharArray, data, stringPool);
-                        }
-                    }
-                }
-            }
-        }
-        return reader;
-    }
-
-    final class XMLDeclReader extends XMLEntityReader {
-        //
-        //
-        //
-        private StringPool fStringPool = null;
-        private ChunkyByteArray fData = null;
-        //
-        //
-        //
-        XMLDeclReader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter, boolean sendCharDataAsCharArray, ChunkyByteArray data, StringPool stringPool) {
-            super(entityHandler, errorReporter, sendCharDataAsCharArray);
-            fStringPool = stringPool;
-            fData = data;
-        }
-        //
-        // These methods are used to parse XMLDecl/TextDecl.
-        //
-        public boolean lookingAtChar(char ch, boolean skipPastChar) throws IOException {
-            if (fData.byteAt(fCurrentOffset) != ch)
-                return false;
-            if (skipPastChar)
-                fCurrentOffset++;
-            return true;
-        }
-        public boolean lookingAtSpace(boolean skipPastChar) throws IOException {
-            int ch = fData.byteAt(fCurrentOffset) & 0xff;
-            if (ch != 0x20 && ch != 0x09 && ch != 0x0A && ch != 0x0D)
-                return false;
-            if (skipPastChar)
-                fCurrentOffset++;
-            return true;
-        }
-        public void skipPastSpaces() throws IOException {
-            while (true) {
-                int ch = fData.byteAt(fCurrentOffset) & 0xff;
-                if (ch != 0x20 && ch != 0x09 && ch != 0x0A && ch != 0x0D)
-                    return;
-                fCurrentOffset++;
-            }
-        }
-        public boolean skippedString(char[] s) throws IOException {
-            int offset = fCurrentOffset;
-            for (int i = 0; i < s.length; i++) {
-                if (fData.byteAt(offset) != s[i])
-                    return false;
-                offset++;
-            }
-            fCurrentOffset = offset;
-            return true;
-        }
-        public int scanStringLiteral() throws Exception {
-            boolean single;
-            if (!(single = lookingAtChar('\'', true)) && !lookingAtChar('\"', true)) {
-                return XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED;
-            }
-            int offset = fCurrentOffset;
-            char qchar = single ? '\'' : '\"';
-            while (true) {
-                byte b = fData.byteAt(fCurrentOffset);
-                if (b == qchar)
-                    break;
-                if (b == -1)
-                    return XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED;
-                fCurrentOffset++;
-            }
-            int length = fCurrentOffset - offset;
-            StringBuffer str = new StringBuffer(length);
-            for (int i = 0; i < length; i++) {
-                str.append((char)fData.byteAt(offset + i));
-            }
-            int stringIndex = fStringPool.addString(str.toString());
-            fCurrentOffset++; // move past qchar
-            return stringIndex;
-        }
-        //
-        // The rest of the methods in XMLReader are not used for parsing XMLDecl/TextDecl.
-        //
-        public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length) {
-            throw new RuntimeException("RDR002 cannot happen");
-        }
-        public int addString(int offset, int length) {
-            throw new RuntimeException("RDR002 cannot happen");
-        }
-        public int addSymbol(int offset, int length) {
-            throw new RuntimeException("RDR002 cannot happen");
-        }
-        public void skipToChar(char ch) throws IOException {
-            throw new IOException("RDR002 cannot happen");
-        }
-        public void skipPastName(char fastcheck) throws IOException {
-            throw new IOException("RDR002 cannot happen");
-        }
-        public void skipPastNmtoken(char fastcheck) throws IOException {
-            throw new IOException("RDR002 cannot happen");
-        }
-        public boolean lookingAtValidChar(boolean skipPastChar) throws IOException {
-            throw new IOException("RDR002 cannot happen");
-        }
-        public int scanInvalidChar() throws IOException {
-            throw new IOException("RDR002 cannot happen");
-        }
-        public int scanCharRef(boolean hex) throws IOException {
-            throw new IOException("RDR002 cannot happen");
-        }
-        public int scanAttValue(char qchar, boolean asSymbol) throws IOException {
-            throw new IOException("RDR002 cannot happen");
-        }
-        public int scanEntityValue(int qchar, boolean createString) throws IOException {
-            throw new IOException("RDR002 cannot happen");
-        }
-        public boolean scanExpectedName(char fastcheck, StringPool.CharArrayRange expectedName) throws IOException {
-            throw new IOException("RDR002 cannot happen");
-        }
-        public void scanQName(char fastcheck, QName qname) throws IOException {
-            throw new IOException("RDR002 cannot happen");
-        }
-        public int scanName(char fastcheck) throws IOException {
-            throw new IOException("RDR002 cannot happen");
-        }
-        public int scanContent(QName element) throws IOException {
-            throw new IOException("RDR002 cannot happen");
-        }
-    }
-}
diff --git a/src/org/apache/xerces/readers/XCatalog.java b/src/org/apache/xerces/readers/XCatalog.java
deleted file mode 100644
index d0ed96a..0000000
--- a/src/org/apache/xerces/readers/XCatalog.java
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLParser;
-import org.apache.xerces.parsers.SAXParser;
-import org.apache.xerces.utils.StringPool;
-
-import org.xml.sax.AttributeList;
-import org.xml.sax.DocumentHandler;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
-
-/**
- * This catalog supports the XCatalog proposal draft 0.2 posted
- * to the xml-dev mailing list by 
- * <a href="mailto:cowan@locke.ccil.org">John Cowan</a>. XCatalog
- * is an XML representation of the SGML Open TR9401:1997 catalog
- * format. The current proposal supports public identifier maps,
- * system identifier aliases, and public identifier prefix 
- * delegates. Refer to the XCatalog DTD for the full specification 
- * of this catalog format at 
- * <a href="http://www.ccil.org/~cowan/XML/XCatalog.html">http://www.ccil.org/~cowan/XML/XCatalog.html</a>.
- * <p>
- * In order to use XCatalogs, you must write the catalog files
- * with the following restrictions:
- * <ul>
- * <li>You must follow the XCatalog grammar.
- * <li>You must specify the <tt>&lt;!DOCTYPE&gt;</tt> line with
- *   the <tt>PUBLIC</tt> specified as "-//DTD XCatalog//EN" or
- *   make sure that the system identifier is able to locate the
- *   XCatalog 0.2 DTD (which is included in the Jar file containing
- *   the org.apache.xerces.readers.XCatalog class).
- *   For example:
- *   <pre>
- *   &lt;!DOCTYPE XCatalog PUBLIC "-//DTD XCatalog//EN" "org/apache/xerces/readers/xcatalog.dtd"&gt;
- *   </pre>
- * <li>The enclosing <tt>&lt;XCatalog&gt;</tt> document root 
- *   element is <b>not</b> optional -- it <b>must</b> be specified.
- * <li>The <tt>Version</tt> attribute of the <tt>&lt;XCatalog&gt;</tt>
- *   has been modified from '<tt><i>#FIXED "1.0"</i></tt>' to 
- *   '<tt><i>(0.1|0.2) "0.2"</i></tt>'.
- * </ul>
- * <p>
- * To use this catalog in a parser, set an XCatalog instance as the
- * parser's <tt>EntityResolver</tt>. For example:
- * <pre>
- *   XMLParser parser  = new AnyParser();
- *   Catalog   catalog = <font color="blue">new XCatalog()</font>;
- *   <font color="blue">parser.getEntityHandler().setEntityResolver(catalog);</font>
- * </pre>
- * <p>
- * Once installed, catalog files that conform to the XCatalog grammar
- * can be appended to the catalog by calling the <tt>loadCatalog</tt>
- * method on the parser or the catalog instance. The following example
- * loads the contents of two catalog files:
- * <pre>
- *   parser.loadCatalog(new InputSource("catalogs/cat1.xml"));
- *   parser.loadCatalog(new InputSource("http://host/catalogs/cat2.xml"));
- * </pre>
- * <p>
- * <b>Limitations:</b> The following are the current limitations
- * of this XCatalog implementation:
- * <ul>
- * <li>No error checking is done to avoid circular <tt>Delegate</tt>
- *   or <tt>Extend</tt> references. Do not specify a combination of
- *   catalog files that reference each other.
- * </ul>
- *
- * @author  Andy Clark, IBM
- * @version $Id$
- */
-public class XCatalog
-    extends XMLCatalogHandler
-    {
-
-    //
-    // Constants
-    //
-
-    // public
-
-    /** XCatalog public identifier string ("-//DTD XCatalog//EN"). */
-    public static final String XCATALOG_DTD_PUBLICID = "-//DTD XCatalog//EN";
-
-    // "default"
-
-    /** XCatalog DTD resource name ("xcatalog.dtd"). */
-    static final String DTD = "xcatalog.dtd";
-
-    /** XCatalog element name ("XCatalog"). */
-    static final String XCATALOG = "XCatalog";
-
-    /** Map element name ("Map"). */
-    static final String MAP = "Map";
-
-    /** PublicID attribute name ("PublicID"). */
-    static final String PUBLICID = "PublicID";
-
-    /** HRef attribute name ("HRef"). */
-    static final String HREF = "HRef";
-
-    /** Delegate element name ("Delegate"). */
-    static final String DELEGATE = "Delegate";
-
-    /** Extend element name ("Extend"). */
-    static final String EXTEND = "Extend";
-
-    /** Base element name ("Base"). */
-    static final String BASE = "Base";
-
-    /** Remap element name ("Remap"). */
-    static final String REMAP = "Remap";
-
-    /** SystemID attribute name ("SystemID"). */
-    static final String SYSTEMID = "SystemID";
-
-    // private
-
-    /** Set to true and recompile to include debugging code in class. */
-    private static final boolean DEBUG = false;
-
-    //
-    // Data
-    //
-
-    /** Delegates. */
-    private Hashtable delegate = new Hashtable();
-
-    /** Delegates ordering. */
-    private Vector delegateOrder = new Vector();
-
-    //
-    // Constructors
-    //
-
-    /** 
-     * Constructs an XCatalog instance.
-     */
-    public XCatalog() {
-    }
-
-    //
-    // Catalog methods
-    //
-
-    /**
-     * Loads the catalog stream specified by the given input source and
-     * appends the contents to the catalog.
-     *
-     * @param source The catalog source.
-     *
-     * @exception org.xml.sax.SAXException Throws exception on SAX error.
-     * @exception java.io.IOException Throws exception on i/o error.
-     */
-    public void loadCatalog(InputSource source)
-        throws SAXException, IOException
-        {
-        
-        new Parser(source);
-
-        /***
-        if (DEBUG) {
-            print("");
-            }
-        /***/
-
-        } // loadCatalog(InputSource)
-
-    /***
-    void print(String indent) {
-        System.out.println(indent+"# "+this);
-        Enumeration maps = getMapKeys();
-        while (maps.hasMoreElements()) {
-            String key   = (String)maps.nextElement();
-            String value = getMapValue(key);
-            System.out.println(indent+"MAP \""+key+"\" -> \""+value+"\"");
-            }
-        Enumeration delegates = getDelegateKeys();
-        while (delegates.hasMoreElements()) {
-            String   key   = (String)delegates.nextElement();
-            XCatalog value = getDelegateValue(key);
-            System.out.println(indent+"DELEGATE \""+key+"\" -> "+value);
-            value.print(indent+"  ");
-            }
-        Enumeration remaps = getRemapKeys();
-        while (remaps.hasMoreElements()) {
-            String key   = (String)remaps.nextElement();
-            String value = getRemapValue(key);
-            System.out.println(indent+"REMAP \""+key+"\" -> \""+value+"\"");
-            }
-        }
-    /***/
-
-    //
-    // EntityResolver methods
-    //
-
-    /**
-     * Resolves external entities.
-     *
-     * @param publicId The public identifier used for entity resolution.
-     * @param systemId If the publicId is not null, this systemId is
-     *                 to be considered the default system identifier;
-     *                 else a system identifier alias mapping is
-     *                 requested.
-     *
-     * @return Returns the input source of the resolved entity or null
-     *         if no resolution is possible.
-     *
-     * @exception org.xml.sax.SAXException Exception thrown on SAX error.
-     * @exception java.io.IOException Exception thrown on i/o error. 
-     */
-    public InputSource resolveEntity(String publicId, String systemId) 
-        throws SAXException, IOException
-        {
-
-        if (DEBUG) {
-            System.out.println("resolveEntity(\""+publicId+"\", \""+systemId+"\")");
-            }
-
-        // public identifier resolution
-        if (publicId != null) {
-            // direct public id mappings
-            String value = getPublicMapping(publicId);
-            if (DEBUG) {
-                System.out.println("  map: \""+publicId+"\" -> \""+value+"\"");
-                }
-            if (value != null) {
-                InputSource source = resolveEntity(null, value);
-                if (source == null) {
-                    source = new InputSource(value);
-                    }
-                source.setPublicId(publicId);
-                return source;
-                }
-
-            // delegates
-            Enumeration delegates = getDelegateCatalogKeys();
-            while (delegates.hasMoreElements()) {
-                String key = (String)delegates.nextElement();
-                if (DEBUG) {
-                    System.out.println("  delegate: \""+key+"\"");
-                    }
-                if (publicId.startsWith(key)) {
-                    XMLCatalogHandler catalog = getDelegateCatalog(key);
-                    InputSource source = catalog.resolveEntity(publicId, systemId);
-                    if (source != null) {
-                        return source;
-                        }
-                    }
-                }
-            }
-
-        // system identifier resolution
-        String value = getSystemMapping(systemId);
-        if (value != null) {
-            if (DEBUG) {
-                System.out.println("  remap: \""+systemId+"\" -> \""+value+"\"");
-                }
-            InputSource source = new InputSource(value);
-            source.setPublicId(publicId);
-            return source;
-            }
-
-        // use default behavior
-        if (DEBUG) {
-            System.out.println("  returning null!");
-            }
-        return null;
-
-        } // resolveEntity(String,String):InputSource
-
-    //
-    // Public methods
-    //
-
-    /** 
-     * Adds a delegate mapping. If the prefix of a public identifier
-     * matches a delegate prefix, then the delegate catalog is
-     * searched in order to resolve the identifier.
-     * <p>
-     * This method makes sure that prefixes that match each other
-     * are inserted into the delegate list in order of longest prefix
-     * length first.
-     *
-     * @param prefix  The delegate prefix.
-     * @param catalog The delegate catalog.
-     */
-    public void addDelegateCatalog(String prefix, XCatalog catalog) {
-
-        synchronized (delegate) {
-            // insert prefix in proper order
-            if (!delegate.containsKey(prefix)) {
-                int size = delegateOrder.size();
-                boolean found = false;
-                for (int i = 0; i < size; i++) {
-                    String element = (String)delegateOrder.elementAt(i);
-                    if (prefix.startsWith(element) || prefix.compareTo(element) < 0) {
-                        delegateOrder.insertElementAt(prefix, i);
-                        found = true;
-                        break;
-                        }
-                    }
-                if (!found) {
-                    delegateOrder.addElement(prefix);
-                    }
-                }
-
-            // replace (or add new) prefix mapping
-            delegate.put(prefix, catalog);
-            }
-
-        } // addDelegateCatalog(String,XCatalog)
-
-    /** 
-     * Removes a delegate. 
-     *
-     * @param prefix The delegate prefix to remove.
-     */
-    public void removeDelegateCatalog(String prefix) {
-
-        synchronized (delegate) {
-            delegate.remove(prefix);
-            delegateOrder.removeElement(prefix);
-            }
-
-        } // removeDelegateCatalog(String)
-
-    /** Returns an enumeration of delegate prefixes. */
-    public Enumeration getDelegateCatalogKeys() {
-        return delegateOrder.elements();
-        }
-
-    /** Returns the catalog for the given delegate prefix. */
-    public XCatalog getDelegateCatalog(String prefix) {
-        return (XCatalog)delegate.get(prefix);
-        }
-
-    //
-    // "default" methods
-    //
-
-    /** Returns true if the string is a valid URL. */
-    boolean isURL(String str) {
-        try {
-            new java.net.URL(str);
-            return true;
-            }
-        catch (java.net.MalformedURLException e) {
-            // assume the worst
-            }
-        return false;
-        }
-
-    //
-    // Classes
-    //
-
-    /** Parser for XCatalog document instances. */
-    class Parser
-        extends SAXParser
-        implements DocumentHandler
-        {
-
-        //
-        // Data
-        //
-
-        /** The base. */
-        private String base;
-
-        //
-        // Constructors
-        //
-
-        /** Parses the specified input source. */
-        public Parser(InputSource source) 
-            throws SAXException, IOException
-            {
-
-            // setup parser
-            setEntityResolver(new Resolver());
-            setDocumentHandler((DocumentHandler)this);
-
-            // set base and parse
-            setBase(source.getSystemId());
-            parse(source);
-
-            } // <init>(InputSource)
-
-        //
-        // Protected methods
-        //
-
-        /** 
-         * Sets the base from the given system identifier. The base is
-         * the same as the system identifier with the least significant
-         * part (the filename) removed.
-         */
-        protected void setBase(String systemId) throws SAXException {
-
-            // normalize system id
-            if (systemId == null) { 
-                systemId = ""; 
-                }
-
-            // expand system id
-            systemId = fEntityHandler.expandSystemId(systemId);
-
-            // cut off the least significant part
-            int index = systemId.lastIndexOf('/');
-            if (index != -1) {
-                systemId = systemId.substring(0, index + 1);
-                }
-
-            // save base
-            base = systemId;
-
-            } // setBase(String)
-
-        //
-        // DocumentHandler methods
-        //
-
-        /** Not implemented. */
-        public void processingInstruction(String target, String data) {}
-
-        /** Not implemented. */
-        public void setDocumentLocator(org.xml.sax.Locator locator) {}
-
-        /** Not implemented. */
-        public void startDocument() {}
-
-        /** Not implemented. */
-        public void endElement(String elementName) {}
-
-        /** Not implemented. */
-        public void endDocument() {}
-
-        /** Not implemented. */
-        public void characters(char ch[], int start, int length) {}
-
-        /** Not implemented. */
-        public void ignorableWhitespace(char ch[], int start, int length) {}
-
-        /** The start of an element. */
-        public void startElement(String elementName, AttributeList attrList) 
-            throws SAXException
-            {
-
-            try {
-                // <XCatalog Version="...">
-                if (elementName.equals(XCATALOG)) {
-                    return;
-                    }
-    
-                // <Map PublicID="..." HRef="..."/>
-                if (elementName.equals(MAP)) {
-                    // get attributes
-                    String publicId = attrList.getValue(PUBLICID);
-                    String href     = attrList.getValue(HREF);
-                    if (DEBUG) {
-                        System.out.println("MAP \""+publicId+"\" \""+href+"\"");
-                        }
-    
-                    // create mapping
-                    if (!isURL(href)) {
-                        href = base + href;
-                        }
-                    addPublicMapping(publicId, href);
-                    }
-    
-                // <Delegate PublicId="..." HRef="..."/>
-                else if (elementName.equals(DELEGATE)) {
-                    // get attributes
-                    String publicId = attrList.getValue(PUBLICID);
-                    String href     = attrList.getValue(HREF);
-                    if (DEBUG) {
-                        System.out.println("DELEGATE \""+publicId+"\" \""+href+"\"");
-                        }
-    
-                    // expand system id
-                    if (!isURL(href)) {
-                        href = base + href;
-                        }
-                    String systemId = fEntityHandler.expandSystemId(href);
-    
-                    // create delegate
-                    XCatalog catalog = new XCatalog();
-                    catalog.loadCatalog(new InputSource(systemId));
-                    addDelegateCatalog(publicId, catalog);
-                    }
-    
-                // <Extend HRef="..."/>
-                else if (elementName.equals(EXTEND)) {
-                    // get attributes
-                    String href = attrList.getValue(HREF);
-                    if (DEBUG) {
-                        System.out.println("EXTEND \""+href+"\"");
-                        }
-    
-                    // expand system id
-                    if (!isURL(href)) {
-                        href = base + href;
-                        }
-                    String systemId = fEntityHandler.expandSystemId(href);
-    
-                    // create catalog
-                    XCatalog.this.loadCatalog(new InputSource(systemId));
-                    }
-    
-                // <Base HRef="..."/>
-                else if (elementName.equals(BASE)) {
-                    // get attributes
-                    String href = attrList.getValue(HREF);
-    
-                    // set new base
-                    setBase(href);
-                    if (DEBUG) {
-                        System.out.println("BASE \""+href+"\" -> \""+base+"\"");
-                        }
-                    }
-                
-                // <Remap SystemID="..." HRef="..."/>
-                else if (elementName.equals(REMAP)) {
-                    // get attributes
-                    String systemId = attrList.getValue(SYSTEMID);
-                    String href     = attrList.getValue(HREF);
-                    if (DEBUG) {
-                        System.out.println("REMAP \""+systemId+"\" \""+href+"\"");
-                        }
-    
-                    // create mapping
-                    if (!isURL(href)) {
-                        href = base + href;
-                        }
-                    addSystemMapping(systemId, href);
-                    }
-                }
-            catch (Exception e) {
-                throw new SAXException(e);
-                }
-
-            } // startElement(String,AttributeList)
-
-        //
-        // Classes
-        //
-
-        /** Resolver for locating the XCatalog DTD resource. */
-        class Resolver
-            implements EntityResolver
-            {
-
-            /** Resolves the XCatalog DTD entity. */
-            public InputSource resolveEntity(String publicId, String systemId) 
-                throws SAXException, IOException
-                {
-
-                // resolve the XCatalog DTD?
-                if (publicId != null && publicId.equals(XCATALOG_DTD_PUBLICID)) {
-                    InputSource src = new InputSource();
-                    src.setPublicId(publicId);
-                    InputStream is = getClass().getResourceAsStream(DTD);
-                    src.setByteStream(is);
-                    src.setCharacterStream(new InputStreamReader(is));
-                    return src;
-                    }
-
-                // no resolution possible
-                return null;
-
-                } // resolveEntity(String,String):InputSource
-
-            } // class Resolver
-
-        } // class Parser
-
-    } // class XCatalog
diff --git a/src/org/apache/xerces/readers/XMLCatalogHandler.java b/src/org/apache/xerces/readers/XMLCatalogHandler.java
deleted file mode 100644
index 05f0278..0000000
--- a/src/org/apache/xerces/readers/XMLCatalogHandler.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-/**
- * Interface for implementing basic catalog support in the parser.
- * To implement and use a Catalog, implement this interface and
- * install your catalog instance as the EntityResolver in the
- * parser's entity handler. For example:
- * <pre>
- *     XMLParser parser = new AnyParser();
- *     <font color="blue">parser.addCatalogHandler(new MyCatalog());</font>
- * </pre>
- * <p>
- * This default catalog implementation does not provide a method
- * for loading multiple catalogs from various input sources.
- * Instead, it is a convenient base class for other catalog
- * implementations.
- * <p>
- * To create a catalog implementation, simply extend this class
- * and implement the <tt>loadCatalog</tt> method. Public and system
- * identifier mappings can be stored and accessed using the 
- * convenient public methods on this class.
- *
- * @author  Andy Clark, IBM
- * @version
- *
- * @see org.xml.sax.EntityResolver
- */
-public abstract class XMLCatalogHandler implements EntityResolver {
-
-    /**
-     * Loads the catalog stream specified by the given input source and
-     * appends the contents to the catalog.
-     *
-     * @param source The catalog source.
-     *
-     * @exception java.lang.Exception Throws an exception if an error
-     *                                occurs while loading the catalog source.
-     */
-    public abstract void loadCatalog(InputSource source) throws Exception;
-
-
-    //
-    // Data
-    //
-
-    /** Public identifier mappings. */
-    private Hashtable publicMap = new Hashtable();
-
-    /** System identifier mappings (aliases). */
-    private Hashtable systemMap = new Hashtable();
-
-    //
-    // Public methods
-    //
-
-    /**
-     * Adds a public to system identifier mapping.
-     *
-     * @param publicId The public identifier, or "key".
-     * @param systemId The system identifier, or "value".
-     */
-    public void addPublicMapping(String publicId, String systemId) {
-        publicMap.put(publicId, systemId);
-    }
-
-    /**
-     * Removes a public identifier mapping.
-     *
-     * @param publicId The public identifier to remove.
-     */
-    public void removePublicMapping(System publicId) {
-        publicMap.remove(publicId);
-    }
-
-    /** Returns an enumeration of public identifier mapping keys. */
-    public Enumeration getPublicMappingKeys() {
-        return publicMap.keys();
-    }
-
-    /**
-     * Returns a public identifier mapping.
-     *
-     * @param publicId The public identifier, or "key".
-     *
-     * @return Returns the system identifier value or null if there
-     *         is no mapping defined.
-     */
-    public String getPublicMapping(String publicId) {
-        return (String)publicMap.get(publicId);
-    }
-
-    /**
-     * Adds a system identifier alias.
-     *
-     * @param publicId The system identifier "key".
-     * @param systemId The system identifier "value".
-     */
-    public void addSystemMapping(String systemId1, String systemId2) {
-        systemMap.put(systemId1, systemId2);
-    }
-
-    /**
-     * Removes a system identifier alias.
-     *
-     * @param systemId The system identifier to remove.
-     */
-    public void removeSystemMapping(String systemId) {
-        systemMap.remove(systemId);
-    }
-
-    /** Returns an enumeration of system identifier mapping keys. */
-    public Enumeration getSystemMappingKeys() {
-        return systemMap.keys();
-    }
-
-    /**
-     * Returns a system identifier alias.
-     *
-     * @param systemId The system identifier "key".
-     *
-     * @return Returns the system identifier alias value or null if there
-     *         is no alias defined.
-     */
-    public String getSystemMapping(String systemId) {
-        return (String)systemMap.get(systemId);
-    }
-
-    /**
-     * Resolves external entities.
-     *
-     * @param publicId The public identifier used for entity resolution.
-     * @param systemId If the publicId is not null, this systemId is
-     *                 to be considered the default system identifier;
-     *                 else a system identifier alias mapping is
-     *                 requested.
-     *
-     * @return Returns the input source of the resolved entity or null
-     *         if no resolution is possible.
-     *
-     * @exception org.xml.sax.SAXException Exception thrown on SAX error.
-     * @exception java.io.IOException Exception thrown on i/o error. 
-     */
-    public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException 
-    {
-        
-        // public id -> system id
-        if (publicId != null) {
-            String value = getPublicMapping(publicId);
-            if (value != null) {
-                return new InputSource(value);
-            }
-        }
-
-        // system id(1) -> system id(2)
-        if (systemId != null) {
-            String value = getSystemMapping(systemId);
-            if (value == null) {
-                value = systemId;
-            }
-
-            return new InputSource(value);
-        }
-
-        return null;
-
-    }
-}
diff --git a/src/org/apache/xerces/readers/XMLDeclRecognizer.java b/src/org/apache/xerces/readers/XMLDeclRecognizer.java
deleted file mode 100644
index fb6f9f2..0000000
--- a/src/org/apache/xerces/readers/XMLDeclRecognizer.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.ChunkyByteArray;
-import org.apache.xerces.utils.StringPool;
-import java.util.Stack;
-
-/**
- * Abstract base class for encoding recognizers.
- *
- * When we encounter an external entity, including the document entity,
- * and do not know what the encoding of the underlying byte stream is,
- * we need to look at the contents of the stream to find out.  We do this
- * by asking a set of "recognizers" to look at the stream data and if
- * the recognizer can understand the encoding it will try to read an
- * XML or text declaration, if present, and construct the appropriate
- * reader for that encoding.  The recognizer subclasses will typically
- * use the prescanXMLDeclOrTextDecl() method if the stream looks like
- * it does begin with such a declaration using a temporary reader that
- * can support the calls needed to scan through the encoding declaration.
- */
-public abstract class XMLDeclRecognizer {
-
-    /**
-     * Register the standard recognizers.
-     *
-     * @param recognizerStack The stack of recognizers used by the parser.
-     */
-    public static void registerDefaultRecognizers(Stack recognizerStack) {
-        recognizerStack.push(new EBCDICRecognizer());
-        recognizerStack.push(new UCSRecognizer());
-        recognizerStack.push(new UTF8Recognizer());
-    }
-
-    /**
-     * Subclasses override this method to support recognizing their encodings.
-     *
-     * @param readerFactory the factory object to use when constructing the entity reader.
-     * @param entityHandler the entity handler to get entity readers from
-     * @param errorReporter where to report errors
-     * @param sendCharDataAsCharArray true if the reader should use char arrays, not string handles.
-     * @param stringPool the <code>StringPool</code> to put strings in
-     * @param data initial bytes to perform recognition on
-     * @param xmlDecl true if attempting to recognize fron an XMLDecl, false if trying to recognize from a TextDecl.
-     * @param allowJavaEncodingName true if Java's encoding names are allowed, false if they are not.
-     * @return The reader that will be used to process the contents of the data stream.
-     * @exception java.lang.Exception
-     */
-    public abstract XMLEntityHandler.EntityReader recognize(XMLEntityReaderFactory readerFactory,
-                                                            XMLEntityHandler entityHandler,
-                                                            XMLErrorReporter errorReporter,
-                                                            boolean sendCharDataAsCharArray,
-                                                            StringPool stringPool,
-                                                            ChunkyByteArray data,
-                                                            boolean xmlDecl,
-                                                            boolean allowJavaEncodingName) throws Exception;
-
-    //
-    // From the standard:
-    //
-    // [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
-    // [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
-    // [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'" )
-    // [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
-    // [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
-    //
-    /**
-     * Support for getting the value of an EncodingDecl using an XMLReader.
-     *
-     * This is the minimal logic from the scanner to recognize an XMLDecl or TextDecl using
-     * the XMLReader interface.
-     *
-     * @param entityReader data source for prescan
-     * @param xmlDecl true if attempting to recognize from an XMLDecl, false if trying to recognize from a TextDecl.
-     * @return <code>StringPool</code> handle to the name of the encoding recognized
-     * @exception java.lang.Exception
-     */
-    protected int prescanXMLDeclOrTextDecl(XMLEntityHandler.EntityReader entityReader, boolean xmlDecl) throws Exception
-    {
-        if (!entityReader.lookingAtChar('<', true)) {
-            return -1;
-        }
-        if (!entityReader.lookingAtChar('?', true)) {
-            return -1;
-        }
-        if (!entityReader.skippedString(xml_string)) {
-            return -1;
-        }
-        entityReader.skipPastSpaces();
-        boolean single;
-        char qchar;
-        if (entityReader.skippedString(version_string)) {
-            entityReader.skipPastSpaces();
-            if (!entityReader.lookingAtChar('=', true)) {
-                return -1;
-            }
-            entityReader.skipPastSpaces();
-            int versionIndex = entityReader.scanStringLiteral();
-            if (versionIndex < 0) {
-                return -1;
-            }
-            if (!entityReader.lookingAtSpace(true)) {
-                return -1;
-            }
-            entityReader.skipPastSpaces();
-        }
-        else if (xmlDecl) {
-            return -1;
-        }
-        if (!entityReader.skippedString(encoding_string)) {
-            return -1;
-        }
-        entityReader.skipPastSpaces();
-        if (!entityReader.lookingAtChar('=', true)) {
-            return -1;
-        }
-        entityReader.skipPastSpaces();
-        int encodingIndex = entityReader.scanStringLiteral();
-        return encodingIndex;
-    }
-    //
-    // [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
-    // [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
-    //
-    private static final char[] xml_string = { 'x','m','l' };
-    //
-    // [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
-    //
-    private static final char[] version_string = { 'v','e','r','s','i','o','n' };
-    //
-    // [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'" )
-    //
-    private static final char[] encoding_string = { 'e','n','c','o','d','i','n','g' };
-}
diff --git a/src/org/apache/xerces/readers/XMLEntityHandler.java b/src/org/apache/xerces/readers/XMLEntityHandler.java
deleted file mode 100644
index 76e43cb..0000000
--- a/src/org/apache/xerces/readers/XMLEntityHandler.java
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringPool;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import java.io.InputStream;
-
-/**
- * This is the interface used for entity management.  This interface
- * is typically implemented by the "parser" class to provide entity
- * management services for the scanner classes.
- *
- * @version $Id$
- */
-public interface XMLEntityHandler extends Locator {
-
-    /**
-     * Special return values for scanCharRef method.  The normal return
-     * value is a unicode character.  These error conditions are defined
-     * using invalid XML unicode code points.
-     */
-    public static final int
-        CHARREF_RESULT_SEMICOLON_REQUIRED  = -1,
-        CHARREF_RESULT_INVALID_CHAR        = -2,
-        CHARREF_RESULT_OUT_OF_RANGE        = -3;
-
-    /**
-     * Special return values for scanStringLiteral method.  The normal
-     * return value is a StringPool handle.  These error conditions are
-     * defined using invalid indices.
-     */
-    public static final int
-        STRINGLIT_RESULT_QUOTE_REQUIRED = -1,
-        STRINGLIT_RESULT_INVALID_CHAR   = -2;
-
-    /**
-     * Special return values for scanAttValue method.  The normal return
-     * value is a StringPool handle for a simple AttValue that was already
-     * correctly normalized for CDATA in the original document.  These
-     * other return values either indicate an error or that the AttValue
-     * needs further processing.
-     */
-    public static final int
-        ATTVALUE_RESULT_COMPLEX         = -1,
-        ATTVALUE_RESULT_LESSTHAN        = -2,
-        ATTVALUE_RESULT_INVALID_CHAR    = -3;
-
-    /**
-     * Special return values for scanEntityValue method.  The normal return
-     * value is a StringPool handle for a simple EntityValue that was entirely
-     * contained within the original document.  These other return values can
-     * either indicate an error or that the EntityValue needs further processing.
-     */
-    public static final int
-        ENTITYVALUE_RESULT_FINISHED     = -1,
-        ENTITYVALUE_RESULT_REFERENCE    = -2,
-        ENTITYVALUE_RESULT_PEREF        = -3,
-        ENTITYVALUE_RESULT_INVALID_CHAR = -4,
-        ENTITYVALUE_RESULT_END_OF_INPUT = -5;
-
-    /**
-     * Return values for the scanContent method.
-     */
-    public static final int
-        CONTENT_RESULT_START_OF_PI              =  0,
-        CONTENT_RESULT_START_OF_COMMENT         =  1,
-        CONTENT_RESULT_START_OF_CDSECT          =  2,
-        CONTENT_RESULT_END_OF_CDSECT            =  3,
-        CONTENT_RESULT_START_OF_ETAG            =  4,
-        CONTENT_RESULT_MATCHING_ETAG            =  5,
-        CONTENT_RESULT_START_OF_ELEMENT         =  6,
-        CONTENT_RESULT_START_OF_CHARREF         =  7,
-        CONTENT_RESULT_START_OF_ENTITYREF       =  8,
-        CONTENT_RESULT_INVALID_CHAR             =  9,
-        CONTENT_RESULT_MARKUP_NOT_RECOGNIZED    = 10,
-        CONTENT_RESULT_MARKUP_END_OF_INPUT      = 11,
-        CONTENT_RESULT_REFERENCE_END_OF_INPUT   = 12;
-
-    /**
-     * This is an enumeration of all the defined entity types.
-     * These are provided to communicate state information to
-     * the clients of the parser.
-     */
-    public static final int
-        ENTITYTYPE_INTERNAL_PE      = 0,
-        ENTITYTYPE_EXTERNAL_PE      = 1,
-        ENTITYTYPE_INTERNAL         = 2,
-        ENTITYTYPE_EXTERNAL         = 3,
-        ENTITYTYPE_UNPARSED         = 4,
-        ENTITYTYPE_DOCUMENT         = 5,
-        ENTITYTYPE_EXTERNAL_SUBSET  = 6;
-
-    /**
-     * This is an enumeration of all the defined contexts in which
-     * an entity reference may appear.  The order is important, as
-     * all explicit general entity references must appear first and
-     * the last of these must be ENTITYREF_IN_CONTENT.  This permits
-     * the test "(context <= ENTITYREF_IN_CONTENT)" to be used as a
-     * quick check for a general entity reference.
-     *
-     * @see #startReadingFromEntity
-     */
-    public static final int
-        ENTITYREF_IN_ATTVALUE = 0,
-        ENTITYREF_IN_DEFAULTATTVALUE = 1,
-        ENTITYREF_IN_CONTENT = 2,
-        ENTITYREF_IN_DTD_AS_MARKUP = 3,
-        ENTITYREF_IN_ENTITYVALUE = 4,
-        ENTITYREF_IN_DTD_WITHIN_MARKUP = 5,
-        ENTITYREF_DOCUMENT = 6,
-        ENTITYREF_EXTERNAL_SUBSET = 7;
-
-    /**
-     * Start reading document from an InputSource.
-     *
-     * @param source The input source for the document to process.
-     * @return <code>true</code> if we were able to open the document source;
-     *         <code>false</code> otherwise.
-     * @exception java.lang.Exception
-     */
-    public boolean startReadingFromDocument(InputSource source) throws Exception;
-
-    /**
-     * Start reading from this entity.
-     *
-     * Note that the reader depth is not used by the reader, but is made
-     * available so that it may be retrieved at end of input to test that
-     * gramatical structures are properly nested within entities.
-     *
-     * @param entityName The entity name handle in the string pool.
-     * @param readerDepth The depth to associate with the reader for this entity.
-     * @param context The context of the entity reference; see ENTITYREF_IN_*.
-     * @return <code>true</code> if the entity might start with a TextDecl;
-     *         <code>false</code> otherwise.
-     * @exception java.lang.Exception
-     */
-    public boolean startReadingFromEntity(int entityName, int readerDepth, int entityContext) throws Exception;
-
-    /**
-     * Expand the system identifier relative to the entity that we are processing.
-     *
-     * @return The expanded system identifier.
-     */
-    public String expandSystemId(String systemId);
-
-    /**
-     * DTD specific entity handler
-     */
-    public interface DTDHandler {
-        /**
-         * Start reading from the external subset of the DTD.
-         *
-         * @param publicId The public identifier for the external subset.
-         * @param systemId The system identifier for the external subset.
-         * @param readerDepth The depth to associate with the reader for the external subset.
-         * @exception java.lang.Exception
-         */
-        public void startReadingFromExternalSubset(String publicId, String systemId, int readerDepth) throws Exception;
-
-        /**
-         * Finished reading from the external subset of the DTD.
-         * @exception java.lang.Exception
-         */
-        public void stopReadingFromExternalSubset() throws Exception;
-
-        /**
-         * Start the scope of an entity declaration.
-         *
-         * @return <code>true</code> on success; otherwise
-         *         <code>false</code> if the entity declaration is recursive.
-         * @exception java.lang.Exception
-         */
-        public boolean startEntityDecl(boolean isPE, int entityName) throws Exception;
-
-        /**
-         * End the scope of an entity declaration.
-         * @exception java.lang.Exception
-         */
-        public void endEntityDecl() throws Exception;
-
-        /**
-         * Declare entities and notations.
-         */
-        public int addInternalPEDecl(int entityName, int value, boolean isExternal) throws Exception;
-        public int addExternalPEDecl(int entityName, int publicId, int systemId, boolean isExternal) throws Exception;
-        public int addInternalEntityDecl(int entityName, int value, boolean isExternal) throws Exception;
-        public int addExternalEntityDecl(int entityName, int publicId, int systemId, boolean isExternal) throws Exception;
-        public int addUnparsedEntityDecl(int entityName, int publicId, int systemId, int notationName, boolean isExternal) throws Exception;
-        public int addNotationDecl(int notationName, int publicId, int systemId, boolean isExternal) throws Exception;
-
-        /**
-         * Check for unparsed entity.
-         *
-         * @param entityName The string handle for the entity name.
-         * @return <code>true</code> if entityName is an unparsed entity; otherwise
-         *         <code>false</code> if entityName is not declared or not an unparsed entity.
-         */
-        public boolean isUnparsedEntity(int entityName);
-
-        /**
-         * Check for declared notation.
-         *
-         * @param notationName The string handle for the notation name.
-         * @return <code>true</code> if notationName is a declared notation; otherwise
-         *         <code>false</code> if notationName is not declared.
-         */
-        public boolean isNotationDeclared(int entityName);
-
-        /**
-         * Remember a required but undeclared notation.
-         */
-        public void addRequiredNotation(int notationName, Locator locator, int majorCode, int minorCode, Object[] args);
-
-        /**
-         * Check required but undeclared notations.
-         */
-        public void checkRequiredNotations() throws Exception;
-    }
-
-    /**
-     * Return a unique identifier for the current reader.
-     */
-    public int getReaderId();
-
-    /**
-     * Set the depth for the current reader.
-     */
-    public void setReaderDepth(int depth);
-
-    /**
-     * Return the depth set for the current reader.
-     */
-    public int getReaderDepth();
-
-    /**
-     * Return the current reader.
-     */
-    public EntityReader getEntityReader();
-
-    /**
-     * This method is called by the reader subclasses at the
-     * end of input.
-     *
-     * @return The reader to use next.
-     * @exception java.lang.Exception
-     */
-    public EntityReader changeReaders() throws Exception;
-
-    /**
-     * This interface is used to store and retrieve character
-     * sequences.  The primary use is for a literal data buffer
-     * where we can construct the values for literal entity
-     * replacement text.  When all of the characters for the
-     * replacement text have been added to the buffer, the
-     * contents are added to the string pool for later use
-     * in constructing a StringReader if the entity is referenced.
-     */
-    public interface CharBuffer {
-        /**
-         * Append a character to this buffer.
-         *
-         * @param ch The character.
-         */
-        public void append(char ch);
-
-        /**
-         * Append characters to this buffer.
-         *
-         * @param chars The char array containing the characters.
-         * @param offset The offset within the char array of the first character to append.
-         * @param length The number of characters to append.
-         */
-        public void append(char[] chars, int offset, int length);
-
-        /**
-         * Get the current length of the buffer.  This is also the
-         * offset of the next character that is added to the buffer.
-         *
-         * @return The length of the buffer.
-         */
-        public int length();
-
-        /**
-         * Add a region of this buffer to the string pool.
-         *
-         * @param offset The offset within this buffer of the first character of the string.
-         * @param length The number of characters in the string.
-         * @return The <code>StringPool</code> handle of the string.
-         */
-        public int addString(int offset, int length);
-    }
-
-    /**
-     * Set the character data handler.
-     */
-    public void setCharDataHandler(XMLEntityHandler.CharDataHandler charDataHandler);
-
-    /**
-     * Get the character data handler.
-     */
-    public XMLEntityHandler.CharDataHandler getCharDataHandler();
-
-    /**
-     * Interface for passing character data.
-     */
-    public interface CharDataHandler {
-        /**
-         * Process character data, character array version
-         * 
-         * @param chars character buffer to be processed
-         * @param offset offset in buffer where the data starts
-         * @param length length of characters to be processed
-         * @exception java.lang.Exception
-         */
-        public void processCharacters(char[] chars, int offset, int length) throws Exception;
-
-        /**
-         * Process character data, <code>StringPool</code> handle version
-         *
-         * @param stringHandle <code>StringPool</code> handle to the character data
-         * @exception java.lang.Exception
-         */
-        public void processCharacters(int stringHandle) throws Exception;
-
-        /**
-         * Process white space data, character array version
-         *
-         * @param chars character buffer to be processed
-         * @param offset offset in buffer where the data starts
-         * @param length length of whitespace to be processed
-         * @exception java.lang.Exception
-         */
-        public void processWhitespace(char[] chars, int offset, int length) throws Exception;
-
-        /**
-         * Process white space data, <code>StringPool</code> handle version
-         *
-         * @param stringHandle <code>StringPool</code> handle to the whitespace
-         * @exception java.lang.Exception
-         */
-        public void processWhitespace(int stringHandle) throws Exception;
-    }
-
-    /**
-     * This is the interface for scanners to process input data
-     * from entities without needing to know the details of the
-     * underlying storage of those entities, or their encodings.
-     *
-     * The methods in this interface have been refined over time
-     * to a rough balance between keeping the XML grammar dependent
-     * code within the scanner classes, and allowing high performance
-     * processing of XML documents.
-     */
-    public interface EntityReader {
-        /**
-         * Return the current offset within this reader.
-         *
-         * @return The offset.
-         */
-        public int currentOffset();
-
-        /**
-         * Return the line number of the current position within the document that we are processing.
-         *
-         * @return The current line number.
-         */
-        public int getLineNumber();
-
-        /**
-         * Return the column number of the current position within the document that we are processing.
-         *
-         * @return The current column number.
-         */
-        public int getColumnNumber();
-
-        /**
-         * This method is provided for scanner implementations.
-         */
-        public void setInCDSect(boolean inCDSect);
-
-        /**
-         * This method is provided for scanner implementations.
-         */
-        public boolean getInCDSect();
-
-        /**
-         * Append the characters processed by this reader associated with <code>offset</code> and
-         * <code>length</code> to the <code>CharBuffer</code>.
-         *
-         * @param charBuffer The <code>CharBuffer</code> to append the characters to.
-         * @param offset The offset within this reader where the copy should start.
-         * @param length The length within this reader where the copy should stop.
-         */
-        public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length);
-
-        /**
-         * Add a string to the <code>StringPool</code> from the characters scanned using this
-         * reader as described by <code>offset</code> and <code>length</code>.
-         *
-         * @param offset The offset within this reader where the characters start.
-         * @param length The length within this reader where the characters end.
-         * @return The <code>StringPool</code> handle for the string.
-         */
-        public int addString(int offset, int length);
-
-        /**
-         * Add a symbol to the <code>StringPool</code> from the characters scanned using this
-         * reader as described by <code>offset</code> and <code>length</code>.
-         *
-         * @param offset The offset within this reader where the characters start.
-         * @param length The length within this reader where the characters end.
-         * @return The <code>StringPool</code> handle for the symbol.
-         */
-        public int addSymbol(int offset, int length);
-
-        /**
-         * Test that the current character is a <code>ch</code> character.
-         *
-         * @param ch The character to match against.
-         * @param skipPastChar If <code>true</code>, we advance past the matched character.
-         * @return <code>true</code> if the current character is a <code>ch</code> character;
-         *         <code>false</code> otherwise.
-         * @exception java.lang.Exception
-         */
-        public boolean lookingAtChar(char ch, boolean skipPastChar) throws Exception;
-
-        /**
-         * Test that the current character is valid.
-         *
-         * @param skipPastChar If <code>true</code>, we advance past the valid character.
-         * @return <code>true</code> if the current character is valid;
-         *         <code>false</code> otherwise.
-         * @exception java.lang.Exception
-         */
-        public boolean lookingAtValidChar(boolean skipPastChar) throws Exception;
-
-        /**
-         * Test that the current character is a whitespace character.
-         *
-         * @param skipPastChar If <code>true</code>, we advance past the whitespace character.
-         * @return <code>true</code> if the current character is whitespace;
-         *         <code>false</code> otherwise.
-         * @exception java.lang.Exception
-         */
-        public boolean lookingAtSpace(boolean skipPastChar) throws Exception;
-
-        /**
-         * Advance through the input data up to the next <code>ch</code> character.
-         *
-         * @param ch The character to search for.
-         * @exception java.lang.Exception
-         */
-        public void skipToChar(char ch) throws Exception;
-
-        /**
-         * Skip past whitespace characters starting at the current position.
-         * @exception java.lang.Exception
-         */
-        public void skipPastSpaces() throws Exception;
-
-        /**
-         * Skip past a sequence of characters that match the XML definition of a Name.
-         * @exception java.lang.Exception
-         */
-        public void skipPastName(char fastcheck) throws Exception;
-
-        /**
-         * Skip past a sequence of characters that match the XML definition of an Nmtoken.
-         * @exception java.lang.Exception
-         */
-        public void skipPastNmtoken(char fastcheck) throws Exception;
-
-        /**
-         * Skip past a sequence of characters that matches the specified character array.
-         *
-         * @param s The characters to match.
-         * @return <code>true</code> if the current character is valid;
-         *         <code>false</code> otherwise.
-         * @exception java.lang.Exception
-         */
-        public boolean skippedString(char[] s) throws Exception;
-
-        /**
-         * Scan an invalid character.
-         *
-         * @return The invalid character as an integer, or -1 if there was a bad encoding.
-         * @exception java.lang.Exception
-         */
-        public int scanInvalidChar() throws Exception;
-
-        /**
-         * Scan a character reference.
-         *
-         * @return The value of the character, or one of the following error codes:
-         *
-         *   CHARREF_RESULT_SEMICOLON_REQUIRED
-         *   CHARREF_RESULT_INVALID_CHAR
-         *   CHARREF_RESULT_OUT_OF_RANGE
-         * @exception java.lang.Exception
-         */
-        public int scanCharRef(boolean isHexadecimal) throws Exception;
-
-        /**
-         * Scan a string literal.
-         *
-         * @return The <code>StringPool</code> handle for the string that
-         *         was scanned, or one of the following error codes:
-         *
-         *   STRINGLIT_RESULT_QUOTE_REQUIRED
-         *   STRINGLIT_RESULT_INVALID_CHAR
-         * @exception java.lang.Exception
-         */
-        public int scanStringLiteral() throws Exception;
-
-        /**
-         * Scan an attribute value.
-         *
-         * @param qchar The initial quote character, either a single or double quote.
-         * @return The <code>StringPool</code> handle for the string that
-         *         was scanned, or one of the following error codes:
-         *
-         *   ATTVALUE_RESULT_COMPLEX
-         *   ATTVALUE_RESULT_LESSTHAN
-         *   ATTVALUE_RESULT_INVALID_CHAR
-         * @exception java.lang.Exception
-         */
-        public int scanAttValue(char qchar, boolean asSymbol) throws Exception;
-
-        /**
-         * Scan an entity value.
-         *
-         * @param qchar The initial quote character, either a single or double quote.
-         * @return The <code>StringPool</code> handle for the string that
-         *         was scanned, or one of the following error codes:
-         *
-         *   ENTITYVALUE_RESULT_FINISHED
-         *   ENTITYVALUE_RESULT_REFERENCE
-         *   ENTITYVALUE_RESULT_PEREF
-         *   ENTITYVALUE_RESULT_INVALID_CHAR
-         *   ENTITYVALUE_RESULT_END_OF_INPUT
-         * @exception java.lang.Exception
-         */
-        public int scanEntityValue(int qchar, boolean createString) throws Exception;
-
-        /**
-         * Add a sequence of characters that match the XML definition of a Name to the <code>StringPool</code>.
-         *
-         * If we find a name at the current position we will add it to the <code>StringPool</code>
-         * as a symbol and will return the string pool handle for that symbol to the caller.
-         *
-         * @param fastcheck A character that is not a legal name character that is provided as a
-         *                  hint to the reader of a character likely to terminate the Name.
-         * @return The <code>StringPool</code> handle for the name that was scanned,
-         *         or -1 if a name was not found at the current position within the input data.
-         * @exception java.lang.Exception
-         */
-        public int scanName(char fastcheck) throws Exception;
-
-        /**
-         * Scan the name that is expected at the current position in the document.
-         *
-         * This method is invoked when we are scanning the element type in an end tag
-         * that must match the element type in the corresponding start tag.
-         *
-         * @param fastcheck A character that is not a legal name character that is provided as a
-         *                  hint to the reader of a character likely to terminate the Name.
-         * @param expectedName The characters of the name we expect.
-         * @return <code>true</code> if we scanned the name we expected to find; otherwise
-         *         <code>false</code> if we did not.
-         * @exception java.lang.Exception
-         */
-        public boolean scanExpectedName(char fastcheck, StringPool.CharArrayRange expectedName) throws Exception;
-
-        /**
-         * Add a sequence of characters that match the XML Namespaces definition of a QName
-         * to the <code>StringPool</code>.
-         *
-         * If we find a QName at the current position we will add it to the <code>StringPool</code>
-         * and will return the string pool handle of that QName to the caller.
-         *
-         * @param fastcheck A character that is not a legal name character that is provided as a
-         *                  hint to the reader of a character likely to terminate the Name.
-         * <!--
-         * @return The <code>StringPool</code> handle for the QName that was scanned,
-         *         or -1 if a name was not found at the current position within the input data.
-         * -->
-         * @exception java.lang.Exception
-         */
-        public void scanQName(char fastcheck, QName qname) throws Exception;
-
-        /**
-         * Skip through the input while we are looking at character data.
-         *
-         * @param elementType The element type handle in the StringPool.
-         * @return One of the following result codes:
-         *
-         *   CONTENT_RESULT_START_OF_PI
-         *   CONTENT_RESULT_START_OF_COMMENT
-         *   CONTENT_RESULT_START_OF_CDSECT
-         *   CONTENT_RESULT_END_OF_CDSECT
-         *   CONTENT_RESULT_START_OF_ETAG
-         *   CONTENT_RESULT_MATCHING_ETAG
-         *   CONTENT_RESULT_START_OF_ELEMENT
-         *   CONTENT_RESULT_START_OF_CHARREF
-         *   CONTENT_RESULT_START_OF_ENTITYREF
-         *   CONTENT_RESULT_INVALID_CHAR
-         *   CONTENT_RESULT_MARKUP_NOT_RECOGNIZED
-         *   CONTENT_RESULT_MARKUP_END_OF_INPUT
-         *   CONTENT_RESULT_REFERENCE_END_OF_INPUT
-         * @exception java.lang.Exception
-         */
-        public int scanContent(QName element) throws Exception;
-    }
-}
diff --git a/src/org/apache/xerces/readers/XMLEntityReader.java b/src/org/apache/xerces/readers/XMLEntityReader.java
deleted file mode 100644
index a19ea42..0000000
--- a/src/org/apache/xerces/readers/XMLEntityReader.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-
-/**
- * This is the class used by the scanner to process the XML data.
- *
- * @see org.apache.xerces.framework.XMLParser
- * @version $Id$
- */
-abstract class XMLEntityReader implements XMLEntityHandler.EntityReader {
-    /*
-     * Instance variables.
-     */
-    protected XMLEntityHandler fEntityHandler = null;
-    protected XMLErrorReporter fErrorReporter = null;
-    protected boolean fSendCharDataAsCharArray;
-    protected XMLEntityHandler.CharDataHandler fCharDataHandler = null;
-    protected boolean fInCDSect = false;
-    private boolean fStillActive = true;
-    /*
-     * These are updated directly by the subclass implementation.
-     */
-    protected int fCarriageReturnCounter = 1;
-    protected int fLinefeedCounter = 1;
-    protected int fCharacterCounter = 1;
-    protected int fCurrentOffset = 0;
-    /**
-     * Constructor
-     */
-    protected XMLEntityReader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter, boolean sendCharDataAsCharArray) {
-        fEntityHandler = entityHandler;
-        fErrorReporter = errorReporter;
-        fSendCharDataAsCharArray = sendCharDataAsCharArray;
-        fCharDataHandler = fEntityHandler.getCharDataHandler();
-    }
-    /**
-     * Constructor
-     */
-    protected XMLEntityReader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter, boolean sendCharDataAsCharArray, int lineNumber, int columnNumber) {
-        fEntityHandler = entityHandler;
-        fErrorReporter = errorReporter;
-        fSendCharDataAsCharArray = sendCharDataAsCharArray;
-        fCharDataHandler = fEntityHandler.getCharDataHandler();
-        fLinefeedCounter = lineNumber;
-        fCharacterCounter = columnNumber;
-    }
-    protected void init(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter, boolean sendCharDataAsCharArray, int lineNumber, int columnNumber) {
-        fEntityHandler = entityHandler;
-        fErrorReporter = errorReporter;
-        fSendCharDataAsCharArray = sendCharDataAsCharArray;
-        fCharDataHandler = fEntityHandler.getCharDataHandler();
-        fLinefeedCounter = lineNumber;
-        fCharacterCounter = columnNumber;
-        fStillActive = true;
-        fInCDSect = false;
-        fCarriageReturnCounter = 1;
-        fCurrentOffset = 0;
-    }
-
-    /**
-     * Return the current offset within this reader.
-     *
-     * @return The offset.
-     */
-    public int currentOffset() {
-        return fCurrentOffset;
-    }
-
-    /**
-     * Return the line number of the current position within the document that we are processing.
-     *
-     * @return The current line number.
-     */
-    public int getLineNumber() {
-        if (fLinefeedCounter > 1)
-            return fLinefeedCounter;
-        else
-            return fCarriageReturnCounter;
-    }
-
-    /**
-     * Return the column number of the current position within the document that we are processing.
-     *
-     * @return The current column number.
-     */
-    public int getColumnNumber() {
-        return fCharacterCounter;
-    }
-
-    /**
-     * This method is provided for scanner implementations.
-     */
-    public void setInCDSect(boolean inCDSect) {
-        fInCDSect = inCDSect;
-    }
-
-    /**
-     * This method is provided for scanner implementations.
-     */
-    public boolean getInCDSect() {
-        return fInCDSect;
-    }
-
-    /**
-     * This method is called by the reader subclasses at the end of input.
-     */
-    protected XMLEntityHandler.EntityReader changeReaders() throws Exception {
-        XMLEntityHandler.EntityReader nextReader = null;
-        if (fStillActive) {
-            nextReader = fEntityHandler.changeReaders();
-            fStillActive = false;
-        }
-        return nextReader;
-    }
-}
diff --git a/src/org/apache/xerces/readers/XMLEntityReaderFactory.java b/src/org/apache/xerces/readers/XMLEntityReaderFactory.java
deleted file mode 100644
index 052a452..0000000
--- a/src/org/apache/xerces/readers/XMLEntityReaderFactory.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.readers;
-
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.utils.StringPool;
-import org.xml.sax.InputSource;
-import java.io.InputStream;
-import java.io.Reader;
-
-/**
- * This is the factory interface used to create readers.
- *
- * @version
- */
-public interface XMLEntityReaderFactory {
-    /**
-     * Adds a recognizer.
-     *
-     * @param recognizer The XML recognizer to add.
-     */
-    public void addRecognizer(XMLDeclRecognizer recognizer);
-
-    /**
-     * Set char data processing preference.
-     */
-    public void setSendCharDataAsCharArray(boolean flag);
-
-    /**
-     *
-     */
-    public void setAllowJavaEncodingName(boolean flag);
-
-    /**
-     *
-     */
-    public boolean getAllowJavaEncodingName();
-
-    /**
-     * Create an entity reader for the source.
-     *
-     * @param source The input source.
-     * @param systemId The system identifier for the input.
-     * @param xmlDecl <code>true</code> if an XMLDecl may be present; otherwise
-     *                <code>false</code> if a TextDecl may be present.
-     * @param stringPool The string pool.
-     * @return The reader that will process the source.
-     * @exception java.lang.Exception
-     */
-    public XMLEntityHandler.EntityReader createReader(XMLEntityHandler entityHandler,
-                                                      XMLErrorReporter errorReporter,
-                                                      InputSource source,
-                                                      String systemId,
-                                                      boolean xmlDecl,
-                                                      StringPool stringPool) throws Exception;
-
-    /**
-     * Create an entity reader for a character stream.
-     *
-     * @param enityHandler The entity handler.
-     * @param errorReporter The error reporter.
-     * @param sendCharDataAsCharArray true if char data should be reported using
-     *                                char arrays instead of string handles.
-     * @param reader The character stream.
-     * @param stringPool The string pool.
-     * @return The reader that will process the character data.
-     * @exception java.lang.Exception
-     */
-    public XMLEntityHandler.EntityReader createCharReader(XMLEntityHandler entityHandler,
-                                                          XMLErrorReporter errorReporter,
-                                                          boolean sendCharDataAsCharArray,
-                                                          Reader reader,
-                                                          StringPool stringPool) throws Exception;
-
-    /**
-     * Create an entity reader for a byte stream encoded in UTF-8.
-     *
-     * @param enityHandler The entity handler.
-     * @param errorReporter The error reporter.
-     * @param sendCharDataAsCharArray true if char data should be reported using
-     *                                char arrays instead of string handles.
-     * @param data The byte stream.
-     * @param stringPool The string pool.
-     * @return The reader that will process the UTF-8 data.
-     * @exception java.lang.Exception
-     */
-    public XMLEntityHandler.EntityReader createUTF8Reader(XMLEntityHandler entityHandler,
-                                                          XMLErrorReporter errorReporter,
-                                                          boolean sendCharDataAsCharArray,
-                                                          InputStream data,
-                                                          StringPool stringPool) throws Exception;
-
-    /**
-     * Create an entity reader for data from a String.
-     *
-     * @param entityHandler The current entity handler.
-     * @param errorReporter The current error reporter.
-     * @param sendCharDataAsCharArray true if char data should be reported using
-     *                                char arrays instead of string handles.
-     * @param lineNumber The line number to return as our position.
-     * @param columnNumber The column number to return as our position.
-     * @param stringHandle The StringPool handle for the data to process.
-     * @param stringPool The string pool.
-     * @param addEnclosingSpaces If true, treat the data to process as if
-     *                           there were a leading and trailing space
-     *                           character enclosing the string data.
-     * @return The reader that will process the string data.
-     * @exception java.lang.Exception
-     */
-    public XMLEntityHandler.EntityReader createStringReader(XMLEntityHandler entityHandler,
-                                                            XMLErrorReporter errorReporter,
-                                                            boolean sendCharDataAsCharArray,
-                                                            int lineNumber,
-                                                            int columnNumber,
-                                                            int stringHandle,
-                                                            StringPool stringPool,
-                                                            boolean addEnclosingSpaces) throws Exception;
-}
diff --git a/src/org/apache/xerces/readers/xcatalog.dtd b/src/org/apache/xerces/readers/xcatalog.dtd
deleted file mode 100644
index 2768e39..0000000
--- a/src/org/apache/xerces/readers/xcatalog.dtd
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="US-ASCII"?>
-<!ELEMENT XCatalog ANY>
-<!ATTLIST XCatalog
-  Version (0.1|0.2) "0.2"
-  >
-
-<!ELEMENT Map EMPTY>
-<!ATTLIST Map
-  PublicID CDATA #REQUIRED
-  HRef     CDATA #REQUIRED
-  >
-
-<!ELEMENT Remap EMPTY>
-<!ATTLIST Remap
-  SystemID CDATA #REQUIRED
-  HRef     CDATA #REQUIRED
-  >
-
-<!ELEMENT Delegate EMPTY>
-<!ATTLIST Delegate
-  PublicID CDATA #REQUIRED
-  HRef     CDATA #REQUIRED
-  >
-
-<!ELEMENT Extend EMPTY>
-<!ATTLIST Extend
-  HRef CDATA #REQUIRED
-  >
-
-<!ELEMENT Base EMPTY>
-<!ATTLIST Base
-  HRef CDATA #REQUIRED
-  >
-
diff --git a/src/org/apache/xerces/utils/Base64.java b/src/org/apache/xerces/utils/Base64.java
deleted file mode 100644
index 51f1ecd..0000000
--- a/src/org/apache/xerces/utils/Base64.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-import java.lang.*;
-
-
-/**
- * This class provides encode/decode for RFC 2045 Base64 as
- * defined by RFC 2045, N. Freed and N. Borenstein. 
- * RFC 2045: Multipurpose Internet Mail Extensions (MIME)
- * Part One: Format of Internet Message Bodies. Reference
- * 1996 Available at: http://www.ietf.org/rfc/rfc2045.txt 
- * This class is used by XML Schema binary format validation
- *
- * @author Jeffrey Rodriguez
- * @version     $Id$
- */
-
-public final class  Base64 {
-    static private final int  BASELENGTH         = 255;       
-    static private final int  LOOKUPLENGTH       = 64;
-    static private final int  TWENTYFOURBITGROUP = 24;
-    static private final int  EIGHTBIT           = 8;
-    static private final int  SIXTEENBIT         = 16;
-    static private final int  SIXBIT             = 6;
-    static private final int  FOURBYTE           = 4;
-    static private final int  SIGN               = -128;
-    static private final byte PAD                = ( byte ) '=';
-    static private final boolean fDebug          = false;
-    static private byte [] base64Alphabet       = new byte[BASELENGTH]; 
-    static private byte [] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
-
-
-    static {
-
-        for (int i = 0; i<BASELENGTH; i++ ) {
-            base64Alphabet[i] = -1; 
-        }
-        for ( int i = 'Z'; i >= 'A'; i-- ) {
-            base64Alphabet[i] = (byte) (i-'A');
-        }
-        for ( int i = 'z'; i>= 'a'; i--) {
-            base64Alphabet[i] = (byte) ( i-'a' + 26);
-        }
-
-        for ( int i = '9'; i >= '0'; i--) {
-            base64Alphabet[i] = (byte) (i-'0' + 52);
-        }
-
-        base64Alphabet['+']  = 62; 
-        base64Alphabet['/']  = 63;
-
-        for (int i = 0; i<=25; i++ )
-            lookUpBase64Alphabet[i] = (byte) ('A'+i );
-
-        for (int i = 26,  j = 0; i<=51; i++, j++ )
-            lookUpBase64Alphabet[i] = (byte) ('a'+ j );
-
-        for (int i = 52,  j = 0; i<=61; i++, j++ )
-            lookUpBase64Alphabet[i] = (byte) ('0' + j );
-        lookUpBase64Alphabet[62] = (byte) '+';
-        lookUpBase64Alphabet[63] = (byte) '/';
-
-    }
-
-    public static boolean isBase64( String isValidString ){
-        return( isArrayByteBase64( isValidString.getBytes()));
-    }
-
-
-    public static boolean isBase64( byte octect ) {
-        //shall we ignore white space? JEFF??
-        return(octect == PAD || base64Alphabet[octect] != -1 ); 
-    }
-
-
-    public static boolean isArrayByteBase64( byte[] arrayOctect ) {
-        int length = arrayOctect.length;
-        if ( length == 0 )
-            return false;
-        for ( int i=0; i < length; i++ ) {
-            if ( Base64.isBase64( arrayOctect[i] ) == false)
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * Encodes hex octects into Base64
-     * 
-     * @param binaryData Array containing binaryData
-     * @return Encoded Base64 array
-     */
-    public static byte[] encode( byte[] binaryData ) {
-        int      lengthDataBits    = binaryData.length*EIGHTBIT;
-        int      fewerThan24bits   = lengthDataBits%TWENTYFOURBITGROUP; 
-        int      numberTriplets    = lengthDataBits/TWENTYFOURBITGROUP;
-        byte     encodedData[]     = null;
-
-
-        if ( fewerThan24bits != 0 ) //data not divisible by 24 bit
-            encodedData = new byte[ (numberTriplets + 1 )*4  ];
-        else // 16 or 8 bit
-            encodedData = new byte[ numberTriplets*4 ];
-
-        byte k=0, l=0, b1=0,b2=0,b3=0;
-
-        int encodedIndex = 0;
-        int dataIndex   = 0;
-        int i           = 0;
-        if (fDebug ) {
-            System.out.println("number of triplets = " + numberTriplets );
-        }
-        for ( i = 0; i<numberTriplets; i++ ) {
-
-            dataIndex = i*3;
-            b1 = binaryData[dataIndex]; 
-            b2 = binaryData[dataIndex + 1];
-            b3 = binaryData[dataIndex + 2];
-
-            if (fDebug) {
-                System.out.println( "b1= " + b1 +", b2= " + b2 + ", b3= " + b3 );
-            }
-
-            l  = (byte)(b2 & 0x0f);
-            k  = (byte)(b1 & 0x03);
-
-            encodedIndex = i*4;
-            byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
-
-            byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); 
-            byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc);
-
-            encodedData[encodedIndex]   = lookUpBase64Alphabet[ val1 ]; 
-            if (fDebug) {
-                System.out.println( "val2 = " + val2 );
-                System.out.println( "k4   = " + (k<<4));
-                System.out.println( "vak  = " + (val2 | (k<<4)));
-            }
-
-            encodedData[encodedIndex+1] = lookUpBase64Alphabet[ val2 | ( k<<4 )];
-            encodedData[encodedIndex+2] = lookUpBase64Alphabet[ (l <<2 ) | val3 ]; 
-            encodedData[encodedIndex+3] = lookUpBase64Alphabet[ b3 & 0x3f ];
-        }
-
-        // form integral number of 6-bit groups
-        dataIndex    = i*3;
-        encodedIndex = i*4;
-        if (fewerThan24bits == EIGHTBIT ) {
-            b1 = binaryData[dataIndex];
-            k = (byte) ( b1 &0x03 );
-            if (fDebug ) {
-                System.out.println("b1=" + b1);
-                System.out.println("b1<<2 = " + (b1>>2) );
-            }
-            byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
-            encodedData[encodedIndex]     = lookUpBase64Alphabet[ val1 ];
-            encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ k<<4 ]; 
-            encodedData[encodedIndex + 2] = PAD;
-            encodedData[encodedIndex + 3] = PAD;
-        } else if ( fewerThan24bits == SIXTEENBIT ) {
-
-            b1 = binaryData[dataIndex];
-            b2 = binaryData[dataIndex +1 ];
-            l = ( byte ) ( b2 &0x0f );
-            k = ( byte ) ( b1 &0x03 );
-
-            byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
-            byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); 
-
-            encodedData[encodedIndex]     = lookUpBase64Alphabet[ val1 ];
-            encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ val2 | ( k<<4 )];
-            encodedData[encodedIndex + 2] = lookUpBase64Alphabet[ l<<2 ]; 
-            encodedData[encodedIndex + 3] = PAD;
-        }
-        return encodedData;
-    }
-
-
-    /**
-     * Decodes Base64 data into octects
-     * 
-     * @param binaryData Byte array containing Base64 data
-     * @return Array containind decoded data.
-     */
-    public static byte[] decode( byte[] base64Data ) {
-        int      numberQuadruple    = base64Data.length/FOURBYTE;
-        byte     decodedData[]      = null;
-        byte     b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0;
-
-        // Throw away anything not in base64Data
-        // Adjust size
-
-        int encodedIndex = 0;
-        int dataIndex    = 0;
-        decodedData      = new byte[ numberQuadruple*3 + 1 ];
-
-        for (int i = 0; i<numberQuadruple; i++ ) {
-            dataIndex = i*4;
-            marker0   = base64Data[dataIndex +2]; 
-            marker1   = base64Data[dataIndex +3]; 
-
-            b1 = base64Alphabet[base64Data[dataIndex]]; 
-            b2 = base64Alphabet[base64Data[dataIndex +1]];
-
-            if ( marker0 != PAD && marker1 != PAD ) {     //No PAD e.g 3cQl
-                b3 = base64Alphabet[ marker0 ];
-                b4 = base64Alphabet[ marker1 ];
-
-                decodedData[encodedIndex]   = (byte)(  b1 <<2 | b2>>4 ) ;
-                decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
-                decodedData[encodedIndex+2] = (byte)( b3<<6 | b4 ); 
-            } else if ( marker0 == PAD ) {               //Two PAD e.g. 3c[Pad][Pad]
-                decodedData[encodedIndex]   = (byte)(  b1 <<2 | b2>>4 ) ; 
-                decodedData[encodedIndex+1] = (byte)((b2 & 0xf)<<4 );  
-                decodedData[encodedIndex+2] = (byte) 0; 
-            } else if ( marker1 == PAD ) {              //One PAD e.g. 3cQ[Pad]
-                b3 = base64Alphabet[ marker0 ];
-
-                decodedData[encodedIndex]   = (byte)(  b1 <<2 | b2>>4 );
-                decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
-                decodedData[encodedIndex+2] = (byte)( b3<<6); 
-            }
-            encodedIndex += 3;
-        }
-        return decodedData;
-
-    }
-}                                                        
diff --git a/src/org/apache/xerces/utils/CharDataChunk.java b/src/org/apache/xerces/utils/CharDataChunk.java
deleted file mode 100644
index 390ff65..0000000
--- a/src/org/apache/xerces/utils/CharDataChunk.java
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-import org.apache.xerces.readers.XMLEntityHandler;
-
-/**
- * This class provides the character buffers used by some of the
- * reader classes.  The instances of this class are reference
- * counted and placed upon a free list for reallocation when no
- * longer in use so that they are reclaimed faster and with less
- * overhead than using the garbage collector.
- *
- * @version
- */
-public final class CharDataChunk implements StringPool.StringProducer {
-    /**
-     * Chunk size constants
-     *
-     * The reader classes use the chunk size directly for better performance.
-     */
-    public static final int CHUNK_SHIFT = 14;           // 2^14 = 16k
-    public static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
-    public static final int CHUNK_MASK = CHUNK_SIZE - 1;
-    /**
-     * Public constructor (factory)
-     *
-     * If there are any free instances available, remove them from the
-     * free list and reinitialize them.  If not, allocate a new one.
-     *
-     * @param stringPool The string pool.
-     * @param prev The chunk that precedes this one, or null if this is
-     *             the first chunk.
-     * @return The instance reused or created.
-     */
-    public static CharDataChunk createChunk(StringPool stringPool, CharDataChunk prev) {
-
-        CharDataChunk newChunk = null;
-        synchronized (CharDataChunk.class) {
-            newChunk = fgFreeChunks;
-            if (newChunk != null) {
-                fgFreeChunks = newChunk.fNextChunk;
-            } else {
-                newChunk = new CharDataChunk();
-            }
-        }
-        newChunk.fStringPool = stringPool;
-        newChunk.fRefCount = 1;             // account for the reference we return to the caller
-        newChunk.fChunk = prev == null ? 0 : prev.fChunk + 1;
-        newChunk.fNextChunk = null;
-        newChunk.fPreviousChunk = prev;
-        if (prev != null) {
-            //
-            // You might think that we should call prev.addRef() here,
-            // and you would normally be correct.  However, the reader
-            // that calls us is doing something like this:
-            //
-            //      fCurrentChunk = CharDataChunk.createChunk(fStringPool, fCurrentChunk);
-            //
-            // During this call, the fCurrentChunk changes from the
-            // previous chunk to this chunk, losing the reference to
-            // the previous chunk.  To avoid needing code like this:
-            //
-            //      CharDataChunk prevChunk = fCurrentChunk;
-            //      fCurrentChunk = CharDataChunk.createChunk(fStringPool, prevChunk);
-            //      prevChunk.releaseChunk();
-            //
-            // We "adopt the reference" to the previous chunk into our
-            // fPreviousChunk field, since the addRef() followed by a
-            // removeRef() from the caller after we return just cancel
-            // each other out.  The previous chunk reference will go
-            // away later when clearPreviousChunk is called.
-            //
-            prev.setNextChunk(newChunk);
-        }
-        return newChunk;
-    }
-    /**
-     * Return the instance that contains the specified offset.
-     *
-     * This method must always be invoked on an instance that
-     * contains the specified offset, or an instance the contains
-     * an offset greater than, i.e. after, the instance we are
-     * to return.
-     *
-     * @param offset The offset to find.
-     * @return The instance containing the offset.
-     */
-    public CharDataChunk chunkFor(int offset) {
-        int firstChunk = offset >> CHUNK_SHIFT;
-        if (firstChunk == fChunk)
-            return this;
-        CharDataChunk dataChunk = fPreviousChunk;
-        while (firstChunk != dataChunk.fChunk)
-            dataChunk = dataChunk.fPreviousChunk;
-        return dataChunk;
-    }
-    /**
-     * Get the character array of this instance.
-     *
-     * The reader classes access the data of each instance directly.
-     * This class only exists to manage the lifetime of the references
-     * to each instance.  It is not intended to hide from the readers
-     * the fact that each instance contains a buffer of character data.
-     *
-     * @return The character data.
-     */
-    public char[] toCharArray() {
-        return fData;
-    }
-    /**
-     * Set the character array for this instance.
-     *
-     * @param data The character data.
-     */
-    public void setCharArray(char[] data) {
-        fData = data;
-    }
-    /**
-     * Get the next chunk.
-     *
-     * @return The instance that follows this one in the list of chunks,
-     *         or null if there is no such instance.
-     */
-    public CharDataChunk nextChunk() {
-        return fNextChunk;
-    }
-    /**
-     * Clean the previous chunk reference.
-     *
-     * When a reader has reached a point where it knows that it will no
-     * longer call the addString, addSymbol, or append methods with an
-     * offset that is contained within a chunk that precedes this one,
-     * it will call this method to clear the reference from this chunk to
-     * the one preceding it.  This allows the references between chunks
-     * to be dropped as we go and allow the unused instances to be placed
-     * upon the free list for reuse.
-     *
-     * @return <code>true</code> if we cleared the previous chunk pointer;
-     *         otherwise <code>false</code> if the pointer is already null.
-     */
-    public boolean clearPreviousChunk() {
-        if (fPreviousChunk != null) {
-            fPreviousChunk.clearNextChunk();
-            fPreviousChunk.removeRef();
-            fPreviousChunk = null;
-            return true;
-        }
-        return false;
-    }
-    /**
-     * Release the reference to this chunk held by the reader that allocated
-     * this instance.  Called at end of input to release the last chunk in the
-     * list used by the reader.
-     */
-    public void releaseChunk() {
-        removeRef();
-    }
-    /**
-     * Add a range from this chunk to the <code>StringPool</code>
-     *
-     * @param offset the offset of the first character to be added
-     * @param length the number of characters to add
-     * @return the <code>StringPool</code> handle that was added.
-     */
-    public int addString(int offset, int length) {
-        int chunk = offset >> CHUNK_SHIFT;
-        if (chunk != fChunk) {
-            if (fPreviousChunk == null)
-                throw new RuntimeException(new ImplementationMessages().createMessage(null, ImplementationMessages.INT_PCN, 0, null));
-            return fPreviousChunk.addString(offset, length);
-        }
-        int lastChunk = (offset + length - 1) >> CHUNK_SHIFT;
-        if (chunk == lastChunk) {
-            addRef();
-            return fStringPool.addString(this, offset & CHUNK_MASK, length);
-        }
-        String str = toString(offset & CHUNK_MASK, length);
-        return fStringPool.addString(str);
-    }
-    /**
-     * Add a range from this chunk to the <code>StringPool</code> as a symbol
-     *
-     * @param offset the offset of the first character to be added
-     * @param length the number of characters to add
-     * @param hashcode hashcode to match to ensure uniqueness
-     * @return the <code>StringPool</code> handle that was added.
-     */
-    public int addSymbol(int offset, int length, int hashcode) {
-        int chunk = offset >> CHUNK_SHIFT;
-        if (chunk != fChunk) {
-            if (fPreviousChunk == null)
-                throw new RuntimeException(new ImplementationMessages().createMessage(null, ImplementationMessages.INT_PCN, 0, null));
-            return fPreviousChunk.addSymbol(offset, length, hashcode);
-        }
-        int lastChunk = (offset + length - 1) >> CHUNK_SHIFT;
-        int index = offset & CHUNK_MASK;
-        if (chunk == lastChunk) {
-            if (hashcode == 0)
-                hashcode = StringHasher.hashChars(fData, index, length);
-            int symbol = fStringPool.lookupSymbol(this, offset & CHUNK_MASK, length, hashcode);
-            if (symbol == -1) {
-                String str = toString(offset & CHUNK_MASK, length);
-                symbol = fStringPool.addNewSymbol(str, hashcode);
-            }
-            return symbol;
-        }
-        String str = toString(offset & CHUNK_MASK, length);
-        return fStringPool.addSymbol(str);
-    }
-    /**
-     * Append data from a <code>CharBuffer</code> to this chunk.
-     *
-     * @param charBuffer the buffer to be appended.
-     * @param offset the offset of the first character to be appended.
-     * @param length the number of characters to append.
-     */
-    public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length) {
-        //
-        // Setup for the operation.
-        //
-        CharDataChunk dataChunk = chunkFor(offset);
-        int index = offset & CHUNK_MASK;
-        int nbytes = (index + length <= CHUNK_SIZE) ? length : CHUNK_SIZE - index;
-        //
-        // Visit each Chunk in turn until we are done.
-        //
-        while (true) {
-            charBuffer.append(dataChunk.fData, index, nbytes);
-            length -= nbytes;
-            if (length == 0)
-                break;
-            dataChunk = dataChunk.fNextChunk;
-            index = 0;
-            nbytes = length <= CHUNK_SIZE ? length : CHUNK_SIZE;
-        }
-    }
-    //
-    // StringProducer interfaces
-    //
-    /**
-     * Return a range of characters as a <code>String</code>.
-     *
-     * @param offset the offset of the first character to convert.
-     * @param length the number of characters to convert.
-     * @return the <code>String</code>
-     */
-    public String toString(int offset, int length) {
-        if (offset + length <= CHUNK_SIZE) {
-            //
-            // All the chars are in the same chunk
-            //
-            return new String(fData, offset, length);
-        }
-        //
-        // The data is spread across chunks, so we need to build it in pieces.
-        //
-        StringBuffer sb = new StringBuffer(length);
-        //
-        // Copy the partial data from the first chunk.
-        //
-        int nbytes = CHUNK_SIZE - offset;
-        sb.append(fData, offset, nbytes);
-        length -= nbytes;
-        //
-        // Use each chunk in turn until we are done.
-        //
-        CharDataChunk aChunk = fNextChunk;
-        do {
-            nbytes = length <= CHUNK_SIZE ? length : CHUNK_SIZE;
-            sb.append(aChunk.fData, 0, nbytes);
-            length -= nbytes;
-            aChunk = aChunk.fNextChunk;
-        } while (length > 0);
-        String retval = sb.toString();
-        sb = null; // REVISIT - does this help gc ?
-        return retval;
-    }
-    /**
-     * Release a string from this chunk
-     *
-     * @param offset the offset of the first character to be released
-     * @param length the number of characters to release.
-     */
-    public void releaseString(int offset, int length) {
-        removeRef();
-    }
-    /**
-     * Compare a range in this chunk and a range in a character array for equality
-     *
-     * @param offset the offset of the first character in the range in this chunk
-     * @param length the number of characters in the range to compare
-     * @param strChars the character array to compare
-     * @param strOffset the offset of the first character in the range in strChars
-     * @param strLength the number of characters to release.
-     * @return true if the ranges are character-wise equal, otherwise false.
-     */
-    public boolean equalsString(int offset, int length, char[] strChars, int strOffset, int strLength) {
-        if (length != strLength)
-            return false;
-        if (offset + length <= CHUNK_SIZE) {
-            //
-            // All the chars are in the same chunk
-            //
-            for (int i = 0; i < length; i++) {
-                if (fData[offset++] != strChars[strOffset++])
-                    return false;
-            }
-            return true;
-        }
-        //
-        // Compare the partial data from the first chunk.
-        //
-        int nbytes = CHUNK_SIZE - offset;
-        length -= nbytes;
-        while (nbytes-- > 0) {
-            if (fData[offset++] != strChars[strOffset++])
-                return false;
-        }
-        //
-        // Check each chunk in turn until we are done.
-        //
-        CharDataChunk aChunk = fNextChunk;
-        do {
-            offset = 0;
-            nbytes = length <= CHUNK_SIZE ? length : CHUNK_SIZE;
-            length -= nbytes;
-            while (nbytes-- > 0) {
-                if (aChunk.fData[offset++] != strChars[strOffset++])
-                    return false;
-            }
-            aChunk = aChunk.fNextChunk;
-        } while (length > 0);
-        return true;
-    }
-    //
-    // Private methods
-    //
-
-    //
-    // Constructor for factory method.
-    //
-    private CharDataChunk() {}
-    //
-    //
-    //
-    private void addRef() {
-        fRefCount++;
-    }
-    //
-    //
-    //
-    private void removeRef() {
-        fRefCount--;
-        if (fRefCount == 0) {
-            fStringPool = null;
-            fChunk = -1;
-            fPreviousChunk = null;
-            synchronized (CharDataChunk.class) {
-                /*** Only keep one free chunk at a time! ***
-                fNextChunk = fgFreeChunks;
-                /***/
-                fNextChunk = null;
-                fgFreeChunks = this;
-            }
-        }
-    }
-    //
-    //
-    //
-    private void clearNextChunk() {
-        if (fNextChunk != null)
-            fNextChunk.removeRef();
-        fNextChunk = null;
-    }
-    //
-    //
-    //
-    private void setNextChunk(CharDataChunk nextChunk) {
-        if (fNextChunk != null) {
-            throw new RuntimeException("CharDataChunk::setNextChunk");
-        }
-        nextChunk.addRef();
-        fNextChunk = nextChunk;
-    }
-    //
-    // Private instance variables.
-    //
-    private StringPool fStringPool;
-    private int fRefCount;
-    private int fChunk;
-    private char[] fData = null;
-    private CharDataChunk fNextChunk;
-    private CharDataChunk fPreviousChunk;
-    private static CharDataChunk fgFreeChunks = null;
-}
diff --git a/src/org/apache/xerces/utils/ChunkyByteArray.java b/src/org/apache/xerces/utils/ChunkyByteArray.java
deleted file mode 100644
index 966e696..0000000
--- a/src/org/apache/xerces/utils/ChunkyByteArray.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * This class is used for accessing the data provided by an InputStream.
- *
- * There are two ways in which this class is used.  The first occurs
- * when we are prescanning the start of the stream to determine the
- * encoding being used.  Since we do not require that the stream be
- * positionable, we wrap it with an instance of this class.  The first
- * "chunk" of the file is read and the data may be accessed directly
- * using the byteAt(offset) method.  After we have determined the
- * encoding of the byte stream, the instance of this class is passed
- * on to the EntityReader that will process the data for the scanner.
- *
- * At this point, the reader may continue to access this instance using
- * the byteAt method, which will continue to read the contents into
- * chunks as required until end of input.  An example of this is the
- * UCSReader.
- *
- * Alternatively, the reader may access this instance as an InputStream
- * which will first return any data that has been reading into the
- * chunks, and will then return the remaining data from the original
- * InputStream directly.
- *
- * @version
- */
-public final class ChunkyByteArray extends InputStream {
-
-    /**
-     * Constructor
-     *
-     * Reads the first chunk.
-     *
-     * @param is The input stream containing the data of the entity.
-     */
-    public ChunkyByteArray(InputStream is) throws IOException {
-        fInputStream = is;
-        fill();
-    }
-
-    /**
-     * Read a byte.
-     *
-     * @return The next byte of the input data or -1 if there is no more data.
-     */
-    public int read() throws IOException {
-        if (fData == null)
-            return fInputStream == null ? -1 : fInputStream.read();
-        int b = (int)(fData[0][fOffset]);
-        if (++fOffset == fLength) {
-            fData = null;
-            if (fLength < CHUNK_SIZE)
-                fInputStream = null;
-        }
-        return b;
-    }
-
-    /**
-     * Read bytes.
-     *
-     * @param buffer The destination for the bytes returned.  If null, then
-     *               the data will discarded instead of returned.
-     * @param offset The offset within the buffer where the first returned
-     *               byte should be placed.
-     * @param length The maximum number of bytes to place in the buffer or discard.
-     * @return The number of bytes actually placed in the buffer or discarded.
-     */
-    public int read(byte buffer[], int offset, int length) throws IOException {
-        int bytesLeft = fLength - fOffset;
-        if (bytesLeft == 0)
-            return fInputStream == null ? -1 : fInputStream.read(buffer, offset, length);
-        if (length <= 0)
-            return 0;
-        byte[] chunk = fData[0];
-        if (length >= bytesLeft) {
-            length = bytesLeft;
-            if (fLength < CHUNK_SIZE)
-                fInputStream = null;
-        }
-        if (buffer == null) {
-            fOffset += length;
-            return length;
-        }
-        int stop = offset + length;
-        do {
-            buffer[offset++] = chunk[fOffset++];
-        } while (offset < stop);
-        return length;
-    }
-
-    /**
-     * Reset position within the data stream back to
-     * the very beginning.
-     */
-    public void rewind() {
-        fOffset = 0;
-    }
-
-    /**
-     * Return a byte of input data at the given offset.
-     *
-     * @param offset The offset in the data stream.
-     * @return The byte at the specified position within the data stream.
-     */
-    public byte byteAt(int offset) throws IOException {
-        int chunk = offset >> CHUNK_SHIFT;
-        int index = offset & CHUNK_MASK;
-        try {
-            return fData[chunk][index];
-        } catch (NullPointerException ex) {
-            // ignore -- let fill create new chunk
-        } catch (ArrayIndexOutOfBoundsException e) {
-            // current chunk array is not big enough; resize
-            byte newdata[][] = new byte[fData.length * 2][];
-            System.arraycopy(fData, 0, newdata, 0, fData.length);
-            fData = newdata;
-        }
-        if (index == 0) {
-            fill();
-            return fData[chunk][index];
-        }
-        return 0;
-    }
-
-    /**
-     * Test to see if an offset is at the end of the input data.
-     *
-     * @param offset A position in the data stream.
-     * @return <code>true</code> if the position is at the end of the data stream;
-     *         <code>false</code> otherwise.
-     */
-    public boolean atEOF(int offset) {
-        return(offset > fLength);
-    }
-
-
-
-    /**
-     * Closes this input Stream
-     * 
-     * @exception IOException
-     */
-    public void close() throws IOException {
-        if ( fInputStream != null ) {
-             fInputStream.close(); 
-             fInputStream = null; // Null it 
-        }
-    }
-
-
-    //
-    // Fill in the next chunk with additional data.
-    //
-    private void fill() throws IOException {
-        int bufnum = fLength >> CHUNK_SHIFT;
-        byte[] data = new byte[CHUNK_SIZE];
-        fData[bufnum] = data;
-        int offset = 0;
-        int capacity = CHUNK_SIZE;
-        int result = 0;
-        do {
-            result = fInputStream.read(data, offset, capacity);
-            if (result == -1) {
-                data[offset] = (byte)0xff;
-                fInputStream.close();
-                fInputStream = null;
-                break;
-            }
-            if (result > 0) {
-                fLength += result;
-                offset += result;
-                capacity -= result;
-            }
-        } while (capacity > 0);
-    }
-    //
-    // Chunk size constants
-    //
-    private static final int CHUNK_SHIFT = 14;           // 2^14 = 16k
-    private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
-    private static final int CHUNK_MASK = CHUNK_SIZE - 1;
-    private static final int INITIAL_CHUNK_COUNT = (1 << (20 - CHUNK_SHIFT));   // 2^20 = 1m
-    //
-    // Instance variables
-    //
-    private InputStream fInputStream = null;
-    private byte[][] fData = new byte[INITIAL_CHUNK_COUNT][];
-    private int fLength = 0;
-    private int fOffset = 0; // for read methods
-}
diff --git a/src/org/apache/xerces/utils/ChunkyCharArray.java b/src/org/apache/xerces/utils/ChunkyCharArray.java
deleted file mode 100644
index 4764e98..0000000
--- a/src/org/apache/xerces/utils/ChunkyCharArray.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-import org.apache.xerces.readers.XMLEntityHandler;
-
-/**
- *
- * @version
- */
-public final class ChunkyCharArray implements XMLEntityHandler.CharBuffer {
-
-    /**
-     * Constructor
-     */
-    public ChunkyCharArray(StringPool stringPool) {
-        fStringPool = stringPool;
-        fCurrentChunk = CharDataChunk.createChunk(stringPool, null);
-    }
-
-    /**
-     *
-     */
-    public int length() {
-        return fLength;
-    }
-
-    /**
-     *
-     */
-    public void append(char ch) {
-        try {
-            fCurrentData[fCurrentIndex] = ch;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            if (fCurrentIndex == CharDataChunk.CHUNK_SIZE) {
-                fCurrentChunk = CharDataChunk.createChunk(fStringPool, fCurrentChunk);
-                fCurrentData = new char[INITIAL_CHUNK_SIZE];
-                fCurrentIndex = 0;
-            } else {
-                char[] newData = new char[fCurrentIndex * 2];
-                System.arraycopy(fCurrentData, 0, newData, 0, fCurrentIndex);
-                fCurrentData = newData;
-            }
-            fCurrentChunk.setCharArray(fCurrentData);
-            fCurrentData[fCurrentIndex] = ch;
-        } catch (NullPointerException ex) {
-            fCurrentData = new char[INITIAL_CHUNK_SIZE];
-            fCurrentChunk.setCharArray(fCurrentData);
-            fCurrentData[fCurrentIndex] = ch;
-        }
-        fCurrentIndex++;
-        fLength++;
-    }
-
-    /**
-     * Append a <code>String</code> to this buffer
-     *
-     * @param s the string to append.
-     */
-    public void append(String s) {
-        int slen = s.length();
-        for (int i = 0; i < slen; i++)
-            append(s.charAt(i));
-    }
-
-    /**
-     *
-     */
-    public void append(char[] ch, int offset, int length) {
-        while (length-- > 0)
-            append(ch[offset++]);
-    }
-
-    /**
-     * Append a <code>ChunkyCharArray</code> to this buffer.
-     *
-     * @param charArray buffer to be appended.
-     * @param offset The offset within charArray of the first character.
-     * @param length The number of characters to append.
-     */
-    public void append(ChunkyCharArray charArray, int offset, int length) {
-        fCurrentChunk.append(charArray, offset, length);
-    }
-
-    /**
-     *
-     */
-    public int addString(int offset, int length) {
-        if (length == 0)
-            return 0;
-        return fCurrentChunk.addString(offset, length);
-    }
-
-    /**
-     * Add a region of this buffer to the <code>StringPool</code> as a symbol
-     * 
-     * @param offset The offset within this buffer of the first character of the string
-     * @param length The number of characters in the symbol
-     */
-    public int addSymbol(int offset, int length) {
-        if (length == 0)
-            return 0;
-        return fCurrentChunk.addSymbol(offset, length, 0);
-    }
-
-    //
-    // Chunk size constants
-    //
-    private static final int INITIAL_CHUNK_SHIFT = 7;        // 2^7 = 128
-    private static final int INITIAL_CHUNK_SIZE = (1 << INITIAL_CHUNK_SHIFT);
-
-    //
-    // Instance variables
-    //
-    private StringPool fStringPool = null;
-    private CharDataChunk fCurrentChunk = null;
-    private char[] fCurrentData = null;
-    private int fCurrentIndex = 0;
-    private int fLength = 0;
-}
diff --git a/src/org/apache/xerces/utils/Hash2intTable.java b/src/org/apache/xerces/utils/Hash2intTable.java
deleted file mode 100644
index 49bab95..0000000
--- a/src/org/apache/xerces/utils/Hash2intTable.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-/**
- * A light-weight hashtable class that takes 2 ints as key and 1 int as value
- * @version
- */
-
-public final class Hash2intTable {
-    
-    
-    private static final int INITIAL_BUCKET_SIZE = 4;
-    private static final int HASHTABLE_SIZE = 256;
-    private int[][] fHashTable = new int[HASHTABLE_SIZE][];
-
-
-    public void put(int key1, int key2, int key3, int value) {
-        int hash = (key1+key2+key3+2) % HASHTABLE_SIZE;
-        int[] bucket = fHashTable[hash];
-        
-        if (bucket == null) {
-            bucket = new int[1 + 4*INITIAL_BUCKET_SIZE];
-            bucket[0] = 1;
-            bucket[1] = key1;
-            bucket[2] = key2;
-            bucket[3] = key3;
-            bucket[4] = value;
-            fHashTable[hash] = bucket;
-        } else {
-            int count = bucket[0];
-            int offset = 1 + 4*count;
-            if (offset == bucket.length) {
-                int newSize = count + INITIAL_BUCKET_SIZE;
-                int[] newBucket = new int[1 + 4*newSize];
-                System.arraycopy(bucket, 0, newBucket, 0, offset);
-                bucket = newBucket;
-                fHashTable[hash] = bucket;
-            }
-            boolean found = false;
-            int j=1;
-            for (int i=0; i<count; i++){
-                if ( bucket[j] == key1 && bucket[j+1] == key2
-                     && bucket[j+2] == key3 ) {
-                    bucket[j+3] = value;
-                    found = true;
-                    break;
-                }
-                j += 4;
-            }
-            if (! found) {
-                bucket[offset++] = key1;
-                bucket[offset++] = key2;
-                bucket[offset++] = key3;
-                bucket[offset]= value;
-                bucket[0] = ++count;
-            }
-            
-        }
-    }
-
-    public int get(int key1, int key2, int key3) {
-        int hash = (key1+key2+key3+2) % HASHTABLE_SIZE;
-        int[] bucket = fHashTable[hash];
-
-        if (bucket == null) {
-            return -1;
-        }
-        int count = bucket[0];
-
-        int j=1;
-        for (int i=0; i<count; i++){
-            if ( bucket[j] == key1 && bucket[j+1] == key2
-                  && bucket[j+2] == key3) {
-                return bucket[j+3];
-            }
-            j += 4;
-        }
-        return -1;
-    }
-
-}  // class Hash2inTable
-
-  
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/org/apache/xerces/utils/HexBin.java b/src/org/apache/xerces/utils/HexBin.java
deleted file mode 100644
index 2470fcd..0000000
--- a/src/org/apache/xerces/utils/HexBin.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-import java.lang.*;
-
-
-/**
- * format validation
- *
- * This class encodes/decodes hexadecimal data
- * @author Jeffrey Rodriguez
- * @version $Id$
- */
-
-public final class  HexBin {
-    static private final int  BASELENGTH   = 255;       
-    static private final int  LOOKUPLENGTH = 16;
-    static private byte [] hexNumberTable       = new byte[BASELENGTH]; 
-    static private byte [] lookUpHexAlphabet = new byte[LOOKUPLENGTH];
-
-
-    static {
-        for (int i = 0; i<BASELENGTH; i++ ) {  
-            hexNumberTable[i] = -1; 
-        }
-        for ( int i = '9'; i >= '0'; i--) {
-            hexNumberTable[i] = (byte) (i-'0');
-        }
-        for ( int i = 'F'; i>= 'A'; i--) {
-            hexNumberTable[i] = (byte) ( i-'A' + 10 );
-        }
-        for ( int i = 'f'; i>= 'a'; i--) {
-           hexNumberTable[i] = (byte) ( i-'a' + 10 );
-        }
-        for(int i = 0; i<=25; i++ )
-           lookUpHexAlphabet[i] = (byte) ('A'+i );
-
-        for(int i = 0; i<10; i++ )
-            lookUpHexAlphabet[i] = (byte) ('0'+i );
-        for(int i = 10; i<=15; i++ )
-            lookUpHexAlphabet[i] = (byte) ('A'+i -10);
-    }
-
-    /**
-     * byte to be tested if it is Base64 alphabet
-     * 
-     * @param octect
-     * @return 
-     */
-    static boolean isHex( byte octect ) {
-        //shall we ignore white space? JEFF??
-        return(hexNumberTable[octect] != -1 ); 
-    }
-
-
-    /**
-     *       Array of bytes to check against Hex Table 
-     * 
-     * @param arrayOctect
-     * @return 
-     */
-    static boolean isArrayByteHex( byte[] arrayOctect ) {
-       int length = arrayOctect.length;
-       if( length == 0 )
-           return false;
-       for( int i=0; i < length; i++ ){   
-           
-           if( HexBin.isHex( arrayOctect[i] ) == false)
-               return false;
-
-       }
-       return true;
-   }
-
-    public static boolean isHex( String isValidString ){
-      return( isArrayByteHex( isValidString.getBytes()));
-  }
-
-
-
-    /**
-     * array of byte to encode
-     * 
-     * @param binaryData
-     * @return return encode binary array
-     */
-    static public byte[] encode( byte[] binaryData ) {
-      int lengthData   = binaryData.length;
-      int lengthEncode = lengthData;
-      byte[] encodedData = new byte[lengthData];
-      for( int i = 0; i<lengthData; i++ ){
-         encodedData[i] = lookUpHexAlphabet[ binaryData[i] ];
-      }
-      return encodedData;
-    }
-
-
-    static public  byte[] decode ( byte[]  binaryData ) {
-      int lengthData   = binaryData.length;
-      int lengthEncode = lengthData;
-      byte[] decodedData = new byte[lengthData];
-      for( int i = 0; i<lengthData; i++ ){
-      decodedData[i] = hexNumberTable[binaryData[i]];
-      }
-     return decodedData;
-    }
-}
diff --git a/src/org/apache/xerces/utils/ISO8601Format.java b/src/org/apache/xerces/utils/ISO8601Format.java
deleted file mode 100644
index d88933a..0000000
--- a/src/org/apache/xerces/utils/ISO8601Format.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xerces.utils;
-
-import java.lang.*;
-
-
-/**
- * This class provides ISO8601 date/time formatting conversion into
- * Java DateFormat, 
- * This is based on ISO Internation Standard 1988-06-15 
- *
-
-
-timeDuration
-============
-PnYnMnDTnHnMnS
-
-Years
-Months
-Days
-
-Hours
-Minutes
-Seconds
-
-x < y iff x-y is positive
-
-
-recurringDuration
-================
-timeDuration that recurrs from a specific origin.
-
-2 constraining facets:
-
-  duration ( timeDuration)
-           0  a single instant of time
-
-  period   ( timeDuration)
-           0 does not recurr 
-
-both duration and period should be given
-
-CCYY-MM-DDThh:mm:ss.sss Z
-
-Z Coordinated Universal Time -
-  difference between the local time and Coordinated Universal Time
-  +/-
-
-
-Derived Datatype timeInstant uses same lexical
-Date, time, timePeriod, recurringDate use truncated version
-
-Suppose we wanted to define a day of the week i.e. a 24 hour duration that recurs every 7 days. This could be done as follows:  
-<simpleType name='dayOfWeek' base='recurringDuration'>
-    <duration value='PT24H'/>
-    <period value='P7D'/>
-</simpleType>
- 
-
-timeInstant
-===========
-
-for Calendar Dates:
-  year - month - day - time designator - hour - minute - second
-
-for ordinal date:
-  year - day - time designator - hour - minute - second
-
-for dates identified by week and day numbers:
-  year - week designator - week - day - time designator - hour - minute - second
-
-T - time designator
-- and :  are separators
-
-T maybe omitted ub applications where there is no risk of confusing a combined date and time.
-
-CCYYMMDDThhmmss
-CCYYMMDDThhmm
-CCYYMMDDThh
-
-
-CCYY-MM-DDThh:mm:ss
-CCYY-MM-DDThh:mm
-CCYY-MM-DDThh
-
-CCYYDDDThhmmss
-CCYYDDDThhmm
-CCYYDDDThh
-
-CCYY-DDDThh:mm:ss
-CCYY-DDDThh:mm
-CCYY-DDDThh
-
-CCYYWwwDThhmmss
-CCYYWwwDThhmm
-CCYYWwwDThh
-
-CCYY-Www-DThh:mm:ss
-CCYY-Www-DThh:mm
-CCYY-Www-DThh
-
-
-TimeInstant has as basetype recurrindDuration where
-duration facet = P0Y
-period   facet = P0Y
-
-1999-05-31T13:20:00-05:00. 
-
-
-
-time
-====
-base type is recurringDuration 
-duration facet = P0Y
-period   facet = PY24H ; since this instance of time occurs every 24 hours
-
-Time are in 24 hour period.
-
-
-Lexical is left truncated representation for timeInstant
-with optional following time zone indicator.
-
-13:20:00-05:00
-
-Basic forms       
-Extended forms
-
-Fractions are indicated by [.] or [,].
-Comma is preferred ( should support both).
-
-Coordinated UTC 
-===============
-
-Time representation as above following immediately without spaces
-by time-zone designator [Z].
-
-Local Time
-==========
-Time difference should be expressed only in:
-hours minutes
-hours
-+/-
-Should not be used alone!
-
-timePeriod
-==========
-baseType - recurringDuration with period face equal to "P0Y" (no recurrence
-Domain is space of Periods of time.
-
-So as per ISO spece is either:
-
-a - duration of tome delimited by a specific start and specific end
-b - quantity of time expressed in one or more specific components
-but not associated with any specific start or end.
-c - A quantity of time associated with a specific start.
-d - A quantity of time associated with a specific end.
-
-two components can be separated by a solidus [/] for a, b, and c
-
-a) basic format:
-   CCYYMMDDThhmmss/CCYYMMDDThhmmss
-
-b) representation of duration of time 
-   Basic format: PnYnMnDTnHnMnS
-
-c) Representation of Period identified by its start and its duration.
-   CCYYMMDDThhmmss/PnYnnMnDTnHnMnS
-
-d) Representation of period identified by its duration and its end.
-   PnYnMnDTnHnMnS/CCYYMMDDThhmmss
-
-date
-====
-
-month
-=====
-
-year
-====
-
-century
-=======
-
-recurringDate
-=============
-
-recurringDay
-============
-
-
-
-TimeInstant
-===========
-
-Combination od date and time values that represent a single instant in time
-
-Space of Gregorian dates and legal times
-Lexical:
-
-
-CCYY-MM-DDThh:mm:ss.ssss
-
-CC Century
-YY Year
-MM Month
-DD day
-Optional -  by default a + is assumed or omitted
-T date/time separator
-hh hour
-mm minute
-ss.sss second  , additional digits may be used
-Additional digits to left can be added to allow for years greater than 9999
-
-CCYY-MM-DDThh:mm:ss.ssss can be followed by a Z to indicate Coordinated Universal
-Time.
-
-To indicate time zone the difference between the local time and Coordinated Universal
-Time, follows the time and consist of a sign, + or - followed by hh:mm
-
-e.g.   1999-05-31T13:20:00-05:00
-
-TimeDuration
-============
-P1Y2M3DT10H30M
-
-PnYnMnDTnH nMnS
-nY number of  Years
-nM number of  Hours
-nD number of  days
-T   date/time separator
-nH number of  hours
-nM number of  minutes
-nS number of  seconds
-
-
-recurringInstant
-===============
-
-Lexical
-=======
-Left truncated representation for timeInstant
-
--CC omitted from the timeInstant representation it means a timeinstant
-that recurs every hundred years.
--CCYY omitted is designated a time instant that recurrs every year.
--Every two character "unit" of the representation that is omitted is indicated
-by a single hyphen "-".
-1:20 pm on May the 31st every year is
---05-31T13:20:00-05:00
-
-
-*/
-
-
-
-
-/**
- *  
- * @author Jeffrey Rodriguez
- * @version
- */
-
-
-public final class ISO8601Format {
-
-//    DateFormat dateJava = 0;
-
-
-    public ISO8601Format( String dateString ){
-
-    }
-   
-    //public DateFormat
-
-
-    
-    /**
-     * Encodes hex octects into Base64
-     * 
-     * @param binaryData Array containing binaryData
-     * @return Encoded Base64 array
-     */
-  
-}                                                        
diff --git a/src/org/apache/xerces/utils/ImplementationMessages.java b/src/org/apache/xerces/utils/ImplementationMessages.java
deleted file mode 100644
index 2666ecf..0000000
--- a/src/org/apache/xerces/utils/ImplementationMessages.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.xerces.utils;
-
-import java.util.Locale;
-import java.util.ResourceBundle;
-import java.util.ListResourceBundle;
-
-/**
- * ImplementationMessages provides messages internal to the parser implementation
- *
- * @version
- */
-public class ImplementationMessages implements XMLMessageProvider {
-    /**
-     * The domain of messages concerning the Xerces implementation.
-     */
-    public static final String XERCES_IMPLEMENTATION_DOMAIN = "http://www.apache.org/xml/xerces.html";
-
-    /**
-     *
-     */
-    public void setLocale(Locale locale) {
-        fLocale = locale;
-    }
-    /**
-     *
-     */
-    public Locale getLocale() {
-        return fLocale;
-    }
-
-    /**
-     * Creates a message from the specified key and replacement
-     * arguments, localized to the given locale.
-     *
-     * @param locale    The requested locale of the message to be
-     *                  created.
-     * @param key       The key for the message text.
-     * @param args      The arguments to be used as replacement text
-     *                  in the message created.
-     */
-    public String createMessage(Locale locale, int majorCode, int minorCode, Object args[]) {
-        boolean throwex = false;
-        if (fResourceBundle == null || locale != fLocale) {
-            if (locale != null)
-                fResourceBundle = ListResourceBundle.getBundle("org.apache.xerces.msg.ImplementationMessages", locale);
-            if (fResourceBundle == null)
-                fResourceBundle = ListResourceBundle.getBundle("org.apache.xerces.msg.ImplementationMessages");
-        }
-        if (majorCode < 0 || majorCode >= fgMessageKeys.length - 1) {
-            majorCode = BAD_MAJORCODE;
-            throwex = true;
-        }
-        String msgKey = fgMessageKeys[majorCode];
-        String msg = fResourceBundle.getString(msgKey);
-        if (args != null) {
-            try {
-                msg = java.text.MessageFormat.format(msg, args);
-            } catch (Exception e) {
-                msg = fResourceBundle.getString(fgMessageKeys[FORMAT_FAILED]);
-                msg += " " + fResourceBundle.getString(msgKey);
-            }
-        }
-        if (throwex) {
-            throw new RuntimeException(msg);
-        }
-        return msg;
-    }
-    //
-    //
-    //
-    private Locale fLocale = null;
-    private ResourceBundle fResourceBundle = null;
-    //
-    //
-    //
-    public static final int
-        BAD_MAJORCODE = 0,  //  majorCode parameter to createMessage was out of bounds
-        ENC4 = 1,           // "Invalid UTF-8 code. (byte: 0x{0})"
-        ENC5 = 2,           // "Invalid UTF-8 code. (bytes: 0x{0} 0x{1})"
-        ENC6 = 3,           // "Invalid UTF-8 code. (bytes: 0x{0} 0x{1} 0x{2})"
-        ENC7 = 4,           // "Invalid UTF-8 code. (bytes: 0x{0} 0x{1} 0x{2} 0x{3})"
-        IO0 = 5,            // "File, \"{0}\", not found."
-        VAL_BST = 6,        // "Invalid ContentSpecNode.NODE_XXX value for binary op CMNode."
-        VAL_CMSI = 7,       // "Invalid CMStateSet bit index."
-        VAL_CST = 8,        // "Unknown ContentSpecNode.NODE_XXX value."
-        VAL_LST = 9,        // "Invalid ContentSpecNode.NODE_XXX value for leaf CMNode."
-        VAL_NIICM = 10,     // "Only * unary ops should be in the internal content model tree."
-        VAL_NPCD = 11,      // "PCData found in non-mixed model content."
-        VAL_UST = 12,       // "Invalid ContentSpecNode.NODE_XXX value for unary op CMNode."
-        VAL_WCGHI = 13,     // "Input to whatCanGoHere() is inconsistent."
-        INT_DCN = 14,       // "Internal Error: dataChunk == NULL"
-        INT_PCN = 15,       // "Internal Error: fPreviousChunk == NULL"
-        FATAL_ERROR = 16,   // "Stopping after fatal error: {0}"
-
-        //
-        // KEEP THIS AT THE END
-        //
-        FORMAT_FAILED = 17; // "Internal Error while formatting error message "
-
-    //
-    // Table of error code to error key strings.
-    //
-    private static final String[] fgMessageKeys = {
-        "BadMajorCode",         //  0, "The majorCode parameter to createMessage was out of bounds."
-        "ENC4",                 //  1, "Invalid UTF-8 code. (byte: 0x{0})"
-        "ENC5",                 //  2, "Invalid UTF-8 code. (bytes: 0x{0} 0x{1})"
-        "ENC6",                 //  3, "Invalid UTF-8 code. (bytes: 0x{0} 0x{1} 0x{2})"
-        "ENC7",                 //  4, "Invalid UTF-8 code. (bytes: 0x{0} 0x{1} 0x{2} 0x{3})"
-        "FileNotFound",         //  5, "File, \"{0}\", not found."
-        "VAL_BST",              //  6, "Invalid ContentSpecNode.NODE_XXX value for binary op CMNode."
-        "VAL_CMSI",             //  7, "Invalid CMStateSet bit index."
-        "VAL_CST",              //  8, "Unknown ContentSpecNode.NODE_XXX value."
-        "VAL_LST",              //  9, "Invalid ContentSpecNode.NODE_XXX value for leaf CMNode."
-        "VAL_NIICM",            // 10, "Only * unary ops should be in the internal content model tree."
-        "VAL_NPCD",             // 11, "PCData found in non-mixed model content."
-        "VAL_UST",              // 12, "Invalid ContentSpecNode.NODE_XXX value for unary op CMNode."
-        "VAL_WCGHI",            // 13, "Input to whatCanGoHere() is inconsistent."
-        "INT_DCN",              // 14, "Internal Error: dataChunk == NULL"
-        "INT_PCN",              // 15, "Internal Error: fPreviousChunk == NULL"
-        "FatalError",           // 16, "Stopping after fatal error: {0}"
-
-        //
-        // KEEP THIS AT THE END
-        //
-        "FormatFailed",         // 17, "An internal error occurred while formatting the following message:"
-        null
-    };
-}
diff --git a/src/org/apache/xerces/utils/Makefile b/src/org/apache/xerces/utils/Makefile
deleted file mode 100644
index b1c1603..0000000
--- a/src/org/apache/xerces/utils/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-# Makefile for directory ./org/apache/xerces/utils
-
-TARGETS=\
-       Base64.class\
-	CharDataChunk.class\
-	ChunkyByteArray.class\
-	ChunkyCharArray.class\
-	Hash2intTable.class\
-	HexBin.class\
-	ImplementationMessages.class\
-	ISO8601Format.class\
-	NamespacesScope.class\
-	QName.class\
-	StringHasher.class\
-	StringPool.class\
-	SymbolCache.class\
-	URI.class\
-	UTF8DataChunk.class\
-	XMLCharacterProperties.class\
-	XMLMessageProvider.class\
-	XMLMessages.class
-
-DIRS = regex
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xerces/utils/NamespacesScope.java b/src/org/apache/xerces/utils/NamespacesScope.java
deleted file mode 100644
index db67ea4..0000000
--- a/src/org/apache/xerces/utils/NamespacesScope.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-/**
- * NamespacesScope provides a data structure for mapping namespace prefixes
- * to their URI's.  The mapping accurately reflects the scoping of namespaces
- * at a particular instant in time.
- */
-public class NamespacesScope {
-    /**
-     * NamespacesHandler allows a client to be notified when namespace scopes change
-     */
-    public interface NamespacesHandler {
-        /**
-         * startNamespaceDeclScope is called when a new namespace scope is created
-         *
-         * @param prefix the StringPool handle of the namespace prefix being declared
-         * @param uri the StringPool handle of the namespace's URI
-         * @exception java.lang.Exception
-         */
-        public void startNamespaceDeclScope(int prefix, int uri) throws Exception;
-        /**
-         * endNamespaceDeclScope is called when a namespace scope ends
-         * 
-         * @param prefix the StringPool handle of the namespace prefix going out of scope
-         * @exception java.lang.Exception
-         */
-        public void endNamespaceDeclScope(int prefix) throws Exception;
-    }
-    public NamespacesScope(NamespacesHandler handler) {
-        fHandler = handler;
-        fNamespaceMappings[0] = new int[9];
-        fNamespaceMappings[0][0] = 1;
-    }
-    /**
-     * set the namespace URI for given prefix
-     *
-     * @param prefix the StringPool handler of the prefix
-     * @param namespace the StringPool handle of the namespace URI
-     */
-    public void setNamespaceForPrefix(int prefix, int namespace) throws Exception {
-        int offset = fNamespaceMappings[fElementDepth][0];
-        if (offset == fNamespaceMappings[fElementDepth].length) {
-            int[] newMappings = new int[offset + 8];
-            System.arraycopy(fNamespaceMappings[fElementDepth], 0, newMappings, 0, offset);
-            fNamespaceMappings[fElementDepth] = newMappings;
-        }
-        fNamespaceMappings[fElementDepth][offset++] = prefix;
-        fNamespaceMappings[fElementDepth][offset++] = namespace;
-        fNamespaceMappings[fElementDepth][0] = offset;
-        if (fElementDepth > 0)
-            fHandler.startNamespaceDeclScope(prefix, namespace);
-    }
-    /**
-     * retreive the namespace URI for a prefix
-     *
-     * @param prefix the StringPool handle of the prefix
-     */
-    public int getNamespaceForPrefix(int prefix) {
-        for (int depth = fElementDepth; depth >= 0; depth--) {
-            int offset = fNamespaceMappings[depth][0];
-            for (int i = 1; i < offset; i += 2) {
-                if (prefix == fNamespaceMappings[depth][i]) {
-                    return fNamespaceMappings[depth][i+1];
-                }
-            }
-        }
-        return -1;
-    }
-    /**
-     *  Add a new namespace mapping
-     */
-    public void increaseDepth() throws Exception {
-        fElementDepth++;
-        if (fElementDepth == fNamespaceMappings.length) {
-            int[][] newMappings = new int[fElementDepth + 8][];
-            System.arraycopy(fNamespaceMappings, 0, newMappings, 0, fElementDepth);
-            fNamespaceMappings = newMappings;
-        }
-        if (fNamespaceMappings[fElementDepth] == null)
-            fNamespaceMappings[fElementDepth] = new int[9];
-        fNamespaceMappings[fElementDepth][0] = 1;
-    }
-    /**
-     *  Remove a namespace mappng
-     */
-    public void decreaseDepth() throws Exception {
-        if (fElementDepth > 0) {
-            int offset = fNamespaceMappings[fElementDepth][0];
-            while (offset > 1) {
-                offset -= 2;
-                fHandler.endNamespaceDeclScope(fNamespaceMappings[fElementDepth][offset]);
-            }
-        }
-        fElementDepth--;
-    }
-    private NamespacesHandler fHandler = null;
-    private int fElementDepth = 0;
-    private int[][] fNamespaceMappings = new int[8][];
-}
diff --git a/src/org/apache/xerces/utils/QName.java b/src/org/apache/xerces/utils/QName.java
deleted file mode 100644
index 3affb08..0000000
--- a/src/org/apache/xerces/utils/QName.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-/** 
- * QName structure useful for gathering the parts of a qualified name.
- *
- * @author Andy Clark
- * @version $Id$
- */
-public class QName {
-
-    //
-    // Data
-    //
-
-    /** Prefix. */
-    public int prefix;
-
-    /** Local part of qname. */
-    public int localpart;
-
-    /** Fully concatenated name. */
-    public int rawname;
-
-    /** URI bound to prefix. */
-    public int uri;
-
-    //
-    // Constructors
-    //
-
-    /** Default constructor. */
-    public QName() {
-        clear();
-    }
-
-    /** Constructs a specified qname. */
-    public QName(int prefix, int localpart, int rawname) {
-        setValues(prefix, localpart, rawname, -1);
-    }
-
-    /** Constructs a specified qname. */
-    public QName(int prefix, int localpart, int rawname, int uri) {
-        setValues(prefix, localpart, rawname, uri);
-    }
-
-    /** Copy constructor. */
-    public QName(QName qname) {
-        setValues(qname);
-    }
-
-    //
-    // Public methods
-    //
-
-    /** Sets the values of the qualified name. */
-    public void setValues(QName qname) {
-        prefix = qname.prefix;
-        localpart = qname.localpart;
-        rawname = qname.rawname;
-        uri = qname.uri;
-    }
-
-    /** Sets the values of the qualified name. */
-    public void setValues(int prefix, int localpart, int rawname) {
-        setValues(prefix, localpart, rawname, -1);
-    }
-
-    /** Sets the values of the qualified name. */
-    public void setValues(int prefix, int localpart, int rawname, int uri) {
-        this.prefix = prefix;
-        this.localpart = localpart;
-        this.rawname = rawname;
-        this.uri = uri;
-    }
-
-    /** Clears all of the values. */
-    public void clear() {
-        prefix = -1;
-        localpart = -1;
-        rawname = -1;
-        uri = -1;
-    }
-
-    //
-    // Object methods
-    //
-
-    /** Returns true if the two objects are equal. */
-    public boolean equals(Object object) {
-        if (object != null && object instanceof QName) {
-            QName qname = (QName)object;
-            return prefix == qname.prefix &&
-                   localpart == qname.localpart &&
-                   rawname == qname.rawname &&
-                   uri == qname.uri;
-        }
-        return false;
-    }
-
-    /** Returns a hash code value. */
-    public int hashCode() {
-        return (localpart << 16) | uri;
-    }
-
-    /** Returns a string representation of this object. */
-    public String toString() {
-        StringBuffer str = new StringBuffer();
-        str.append("prefix: ");
-        str.append(prefix);
-        str.append(", ");
-        str.append("localpart: ");
-        str.append(localpart);
-        str.append(", ");
-        str.append("rawname: ");
-        str.append(rawname);
-        str.append(", ");
-        str.append("uri: ");
-        str.append(uri);
-        return str.toString();
-    }
-
-} // class QName
diff --git a/src/org/apache/xerces/utils/StringHasher.java b/src/org/apache/xerces/utils/StringHasher.java
deleted file mode 100644
index f3ef59a..0000000
--- a/src/org/apache/xerces/utils/StringHasher.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-/**
- * Algorithm used to hash char arrays (strings).
- *
- * This class was created after it was discovered that parsing some
- * documents was unexpectedly slow due to many different strings
- * hashing to the same 32-bit value using the java.lang.String hash
- * algorithm.
- *
- * The trick seems to be the shift of the top eight bits of the hashcode
- * back down to the bottom to keep them from being rolled out.
- *
- * @version
- */
-public final class StringHasher {
-    /**
-     * generate a hashcode for a String
-     *
-     * @param str the String to hash
-     * @param strLength the length of the String to hash
-     * @return hashcode for the String
-     */
-    public static int hashString(String str, int strLength) {
-        int hashcode = 0;
-        for (int i = 0; i < strLength; i++) {
-            int top = hashcode >> 24;
-            hashcode += ((hashcode * 37) + top + ((int)str.charAt(i)));
-        }
-        hashcode = (hashcode & 0x7fffffff);
-        return (hashcode == 0) ? 1 : hashcode;
-    }
-    /**
-     * generate a hashcode for a character array
-     *
-     * @param chars the array to hash
-     * @param offset the offset to start hashing
-     * @param length the length of characters to hash
-     * @return hashcode for the character array
-     */
-    public static int hashChars(char[] chars, int offset, int length) {
-        int hashcode = 0;
-        for (int i = 0; i < length; i++) {
-            int top = hashcode >> 24;
-            hashcode += ((hashcode * 37) + top + ((int)(chars[offset++] & 0xFFFF)));
-        }
-        hashcode = (hashcode & 0x7fffffff);
-        return (hashcode == 0) ? 1 : hashcode;
-    }
-    /**
-     * generate partially completed character hashcode.
-     * this is mean to be iterated over individual characters in order to generate
-     * a full hash value
-     * @see #finishHash(int)
-     *
-     * @param hashcode a partially completed character hashcode
-     * @param ch the character to hash
-     * @return a partially completed character hashcode
-     */
-    public static int hashChar(int hashcode, int ch) {
-        int top = hashcode >> 24;
-        hashcode += ((hashcode * 37) + top + ch);
-        return hashcode;
-    }
-    /**
-     * finish hashing a partically completed character hashcode
-     * @see #hashChar(int,int)
-     * 
-     * @param hashcode a partially completed character hashcode
-     * @return a character hashcode
-     */
-    public static int finishHash(int hashcode) {
-        hashcode = (hashcode & 0x7fffffff);
-        return (hashcode == 0) ? 1 : hashcode;
-    }
-}
diff --git a/src/org/apache/xerces/utils/StringPool.java b/src/org/apache/xerces/utils/StringPool.java
deleted file mode 100644
index 37ca513..0000000
--- a/src/org/apache/xerces/utils/StringPool.java
+++ /dev/null
@@ -1,717 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-/**
- *
- * @version
- */
-public final class StringPool {
-    //
-    // Debugging
-    //
-    private static final boolean DEBUG_ADDITIONS = false;
-    /**
-     * Constants
-     */
-    public static final int NULL_STRING = -1;   // null
-    public static final int EMPTY_STRING = 0;   // ""
-    /**
-     *
-     */
-    public interface StringProducer {
-        /**
-         *
-         */
-        public String toString(int offset, int length);
-        /**
-         *
-         */
-        public void releaseString(int offset, int length);
-        /**
-         *
-         */
-        public boolean equalsString(int offset, int length, char[] strChars, int strOffset, int strLength);
-    };
-    //
-    // Chunk size constants
-    //
-    private static final int INITIAL_CHUNK_SHIFT = 8;    // 2^8 = 256
-    private static final int INITIAL_CHUNK_SIZE = (1 << INITIAL_CHUNK_SHIFT);
-    private static final int CHUNK_SHIFT = 13;           // 2^13 = 8k
-    private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
-    private static final int CHUNK_MASK = CHUNK_SIZE - 1;
-    private static final int INITIAL_CHUNK_COUNT = (1 << (16 - CHUNK_SHIFT));   // 2^16 = 64k
-    //
-    // Instance variables
-    //
-    //
-    // String and Symbol arrays
-    //
-    private int fStringCount = 0;
-    private int fStringFreeList = -1;
-    private String[][] fString = new String[INITIAL_CHUNK_COUNT][];
-    private StringPool.StringProducer[][] fStringProducer = new StringPool.StringProducer[INITIAL_CHUNK_COUNT][];
-    private int[][] fOffset = new int[INITIAL_CHUNK_COUNT][];
-    private int[][] fLength = new int[INITIAL_CHUNK_COUNT][];
-    private int[][] fCharsOffset = new int[INITIAL_CHUNK_COUNT][];
-    //
-    // String Lists
-    //
-    private int fStringListCount = 0;
-    private int fActiveStringList = -1;
-    private int[][] fStringList = new int[INITIAL_CHUNK_COUNT][];
-    //
-    // Symbol Hashtable
-    //
-    private static final int INITIAL_BUCKET_SIZE = 4;
-    private static final int HASHTABLE_SIZE = 128;
-    private int[][] fSymbolTable = new int[HASHTABLE_SIZE][];
-    //
-    // Symbol Cache
-    //
-    private SymbolCache fSymbolCache = null;
-    //
-    //
-    //
-    public StringPool() {
-        fSymbolCache = new SymbolCache();
-        if (addSymbol("") != EMPTY_STRING)
-            throw new RuntimeException("UTL002 cannot happen");
-    }
-    //
-    //
-    //
-    public void reset() {
-        int chunk = 0;
-        int index = 0;
-        for (int i = 0; i < fStringCount; i++) {
-            fString[chunk][index] = null;
-            if (fStringProducer[chunk][index] != null)
-                fStringProducer[chunk][index].releaseString(fOffset[chunk][index], fLength[chunk][index]);
-            fStringProducer[chunk][index] = null;
-            if (++index == CHUNK_SIZE) {
-                chunk++;
-                index = 0;
-            }
-        }
-        for (int i = 0; i < HASHTABLE_SIZE; i++)
-            fSymbolTable[i] = null;
-        fStringCount = 0;
-        fStringFreeList = -1;
-        fStringListCount = 0;
-        fActiveStringList = -1;
-        fSymbolCache.reset();
-        fShuffleCount = 0;
-        if (addSymbol("") != EMPTY_STRING)
-            throw new RuntimeException("UTL002 cannot happen");
-    }
-    //
-    // String interfaces
-    //
-    private boolean ensureCapacity(int chunk, int index) {
-        try {
-            return fOffset[chunk][index] == 0;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            if (index == 0) {
-                String[][] newString = new String[chunk * 2][];
-                System.arraycopy(fString, 0, newString, 0, chunk);
-                fString = newString;
-                StringPool.StringProducer[][] newProducer = new StringPool.StringProducer[chunk * 2][];
-                System.arraycopy(fStringProducer, 0, newProducer, 0, chunk);
-                fStringProducer = newProducer;
-                int[][] newInt = new int[chunk * 2][];
-                System.arraycopy(fOffset, 0, newInt, 0, chunk);
-                fOffset = newInt;
-                newInt = new int[chunk * 2][];
-                System.arraycopy(fLength, 0, newInt, 0, chunk);
-                fLength = newInt;
-                newInt = new int[chunk * 2][];
-                System.arraycopy(fCharsOffset, 0, newInt, 0, chunk);
-                fCharsOffset = newInt;
-            } else {
-                String[] newString = new String[index * 2];
-                System.arraycopy(fString[chunk], 0, newString, 0, index);
-                fString[chunk] = newString;
-                StringPool.StringProducer[] newProducer = new StringPool.StringProducer[index * 2];
-                System.arraycopy(fStringProducer[chunk], 0, newProducer, 0, index);
-                fStringProducer[chunk] = newProducer;
-                int[] newInt = new int[index * 2];
-                System.arraycopy(fOffset[chunk], 0, newInt, 0, index);
-                fOffset[chunk] = newInt;
-                newInt = new int[index * 2];
-                System.arraycopy(fLength[chunk], 0, newInt, 0, index);
-                fLength[chunk] = newInt;
-                newInt = new int[index * 2];
-                System.arraycopy(fCharsOffset[chunk], 0, newInt, 0, index);
-                fCharsOffset[chunk] = newInt;
-                return true;
-            }
-        } catch (NullPointerException ex) {
-        }
-        fString[chunk] = new String[INITIAL_CHUNK_SIZE];
-        fStringProducer[chunk] = new StringPool.StringProducer[INITIAL_CHUNK_SIZE];
-        fOffset[chunk] = new int[INITIAL_CHUNK_SIZE];
-        fLength[chunk] = new int[INITIAL_CHUNK_SIZE];
-        fCharsOffset[chunk] = new int[INITIAL_CHUNK_SIZE];
-        return true;
-    }
-    public int addString(String str) {
-        int chunk;
-        int index;
-        int stringIndex;
-        if (fStringFreeList != -1) {
-            stringIndex = fStringFreeList;
-            chunk = stringIndex >> CHUNK_SHIFT;
-            index = stringIndex & CHUNK_MASK;
-            fStringFreeList = fOffset[chunk][index];
-        } else {
-            stringIndex = fStringCount++;
-            chunk = stringIndex >> CHUNK_SHIFT;
-            index = stringIndex & CHUNK_MASK;
-            ensureCapacity(chunk, index);
-        }
-        fString[chunk][index] = str;
-        fStringProducer[chunk][index] = null;
-        fOffset[chunk][index] = 0;
-        fLength[chunk][index] = str.length();
-        fCharsOffset[chunk][index] = -1;
-        if (DEBUG_ADDITIONS)
-            System.err.println("addString(" + str + ") " + stringIndex);
-        return stringIndex;
-    }
-    public int addString(StringPool.StringProducer stringProducer, int offset, int length)
-    {
-        int chunk;
-        int index;
-        int stringIndex;
-        if (fStringFreeList != -1) {
-            stringIndex = fStringFreeList;
-            chunk = stringIndex >> CHUNK_SHIFT;
-            index = stringIndex & CHUNK_MASK;
-            fStringFreeList = fOffset[chunk][index];
-        } else {
-            stringIndex = fStringCount++;
-            chunk = stringIndex >> CHUNK_SHIFT;
-            index = stringIndex & CHUNK_MASK;
-            ensureCapacity(chunk, index);
-        }
-        fString[chunk][index] = null;
-        fStringProducer[chunk][index] = stringProducer;
-        fOffset[chunk][index] = offset;
-        fLength[chunk][index] = length;
-        fCharsOffset[chunk][index] = -1;
-        if (DEBUG_ADDITIONS)
-            System.err.println("addString(" + stringProducer.toString(offset, length) + ") " + stringIndex);
-        return stringIndex;
-    }
-    //
-    // Symbol interfaces
-    //
-    public SymbolCache getSymbolCache() {
-        return fSymbolCache;
-    }
-    //private static int fShuffleCount = 0;
-    private int fShuffleCount = 0;
-    public void resetShuffleCount() {
-        fShuffleCount = 0;
-    }
-    public void updateCacheLine(int symbolIndex, int totalMisses, int length) {
-//System.err.println("found symbol " + toString(symbolIndex) + " after " + totalMisses + " total misses (" + (totalMisses/length) + " misses per character).");
-        if (++fShuffleCount > 200) {
-//            if (fShuffleCount == 201) System.out.println("Stopped shuffling...");
-            return;
-        }
-//        if ((fShuffleCount % 10) == 0) System.out.println("Shuffling pass " + fShuffleCount + " ...");
-        int chunk = symbolIndex >> CHUNK_SHIFT;
-        int index = symbolIndex & CHUNK_MASK;
-        int charsOffset = fCharsOffset[chunk][index];
-        fSymbolCache.updateCacheLine(charsOffset, totalMisses, length);
-    }
-    public int createNonMatchingSymbol(int startOffset,
-                                       int entry,
-                                       int[] entries,
-                                       int offset) throws Exception
-    {
-        int chunk;
-        int index;
-        int stringIndex;
-        if (fStringFreeList != -1) {
-            stringIndex = fStringFreeList;
-            chunk = stringIndex >> CHUNK_SHIFT;
-            index = stringIndex & CHUNK_MASK;
-            fStringFreeList = fOffset[chunk][index];
-        } else {
-            stringIndex = fStringCount++;
-            chunk = stringIndex >> CHUNK_SHIFT;
-            index = stringIndex & CHUNK_MASK;
-            ensureCapacity(chunk, index);
-        }
-        String str = fSymbolCache.createSymbol(stringIndex, startOffset, entry, entries, offset);
-        int slen = str.length();
-        fString[chunk][index] = str;
-        fStringProducer[chunk][index] = null;
-        fOffset[chunk][index] = -1;
-        fLength[chunk][index] = slen;
-        fCharsOffset[chunk][index] = startOffset;
-
-        int hashcode = StringHasher.hashString(str, slen);
-        int hc = hashcode % HASHTABLE_SIZE;
-        int[] bucket = fSymbolTable[hc];
-        hashSymbol(bucket, hashcode, chunk, index);
-        if (DEBUG_ADDITIONS)
-            System.err.println("addSymbolNew(" + str + ") " + stringIndex);
-        return stringIndex;
-    }
-    private void hashSymbol(int[] bucket, int hashcode, int chunk, int index) {
-        if (bucket == null) {
-            bucket = new int[1 + (INITIAL_BUCKET_SIZE * 3)];
-            bucket[0] = 1;
-            bucket[1] = hashcode;
-            bucket[2] = chunk;
-            bucket[3] = index;
-            int hc = hashcode % HASHTABLE_SIZE;
-            fSymbolTable[hc] = bucket;
-        } else {
-            int count = bucket[0];
-            int offset = 1 + (count * 3);
-            if (offset == bucket.length) {
-                int newSize = count + INITIAL_BUCKET_SIZE;
-                int[] newBucket = new int[1 + (newSize * 3)];
-                System.arraycopy(bucket, 0, newBucket, 0, offset);
-                bucket = newBucket;
-                int hc = hashcode % HASHTABLE_SIZE;
-                fSymbolTable[hc] = bucket;
-            }
-            bucket[offset++] = hashcode;
-            bucket[offset++] = chunk;
-            bucket[offset++] = index;
-            bucket[0] = ++count;
-        }
-    }
-    public int addSymbol(String str) {
-        int slen = str.length();
-        int hashcode = StringHasher.hashString(str, slen);
-        int hc = hashcode % HASHTABLE_SIZE;
-        int[] bucket = fSymbolTable[hc];
-        if (bucket != null) {
-            int j = 1;
-            for (int i = 0; i < bucket[0]; i++) {
-                if (bucket[j] == hashcode) {
-                    int chunk = bucket[j+1];
-                    int index = bucket[j+2];
-                    if (slen == fLength[chunk][index]) {
-                        int symoff = fCharsOffset[chunk][index];
-                        boolean match = true;
-                        char[] symbolChars = fSymbolCache.getSymbolChars();
-                        for (int k = 0; k < slen; k++) {
-                            if (symbolChars[symoff++] != str.charAt(k)) {
-                                match = false;
-                                break;
-                            }
-                        }
-                        if (match) {
-                            return (chunk << CHUNK_SHIFT) + index;
-                        }
-                    }
-                }
-                j += 3;
-            }
-        }
-        int chunk;
-        int index;
-        int stringIndex;
-        if (fStringFreeList != -1) {
-            stringIndex = fStringFreeList;
-            chunk = stringIndex >> CHUNK_SHIFT;
-            index = stringIndex & CHUNK_MASK;
-            fStringFreeList = fOffset[chunk][index];
-        } else {
-            stringIndex = fStringCount++;
-            chunk = stringIndex >> CHUNK_SHIFT;
-            index = stringIndex & CHUNK_MASK;
-            ensureCapacity(chunk, index);
-        }
-        fString[chunk][index] = str;
-        fStringProducer[chunk][index] = null;
-        fOffset[chunk][index] = -1;
-        fLength[chunk][index] = slen;
-        fCharsOffset[chunk][index] = fSymbolCache.addSymbolToCache(str, slen, stringIndex);
-
-        hashSymbol(bucket, hashcode, chunk, index);
-        if (DEBUG_ADDITIONS)
-            System.err.println("addSymbolNew(" + str + ") " + stringIndex);
-        return stringIndex;
-    }
-    public int addSymbol(StringPool.StringProducer stringProducer, int offset, int length, int hashcode) {
-        int hc = hashcode % HASHTABLE_SIZE;
-        int[] bucket = fSymbolTable[hc];
-        if (bucket != null) {
-            int j = 1;
-            for (int i = 0; i < bucket[0]; i++) {
-                if (bucket[j] == hashcode) {
-                    int chunk = bucket[j+1];
-                    int index = bucket[j+2];
-                    char[] symbolChars = fSymbolCache.getSymbolChars();
-                    if (stringProducer.equalsString(offset, length, symbolChars, fCharsOffset[chunk][index], fLength[chunk][index])) {
-                        stringProducer.releaseString(offset, length);
-                        return (chunk << CHUNK_SHIFT) + index;
-                    }
-                }
-                j += 3;
-            }
-        }
-        int chunk;
-        int index;
-        int stringIndex;
-        if (fStringFreeList != -1) {
-            stringIndex = fStringFreeList;
-            chunk = stringIndex >> CHUNK_SHIFT;
-            index = stringIndex & CHUNK_MASK;
-            fStringFreeList = fOffset[chunk][index];
-        } else {
-            stringIndex = fStringCount++;
-            chunk = stringIndex >> CHUNK_SHIFT;
-            index = stringIndex & CHUNK_MASK;
-            ensureCapacity(chunk, index);
-        }
-        String str = stringProducer.toString(offset, length);
-        stringProducer.releaseString(offset, length);
-        int slen = str.length();
-        fString[chunk][index] = str;
-        fStringProducer[chunk][index] = null;
-        fOffset[chunk][index] = -1;
-        fLength[chunk][index] = slen;
-        fCharsOffset[chunk][index] = fSymbolCache.addSymbolToCache(str, slen, stringIndex);
-
-        hashSymbol(bucket, hashcode, chunk, index);
-        if (DEBUG_ADDITIONS)
-            System.err.println("addSymbol(" + str + ") " + stringIndex);
-        return stringIndex;
-    }
-    public int lookupSymbol(StringPool.StringProducer stringProducer, int offset, int length, int hashcode) {
-        int hc = hashcode % HASHTABLE_SIZE;
-        int[] bucket = fSymbolTable[hc];
-        if (bucket != null) {
-            int j = 1;
-            for (int i = 0; i < bucket[0]; i++) {
-                if (bucket[j] == hashcode) {
-                    int chunk = bucket[j+1];
-                    int index = bucket[j+2];
-                    char[] symbolChars = fSymbolCache.getSymbolChars();
-                    if (stringProducer.equalsString(offset, length, symbolChars, fCharsOffset[chunk][index], fLength[chunk][index])) {
-                        return (chunk << CHUNK_SHIFT) + index;
-                    }
-                }
-                j += 3;
-            }
-        }
-        return -1;
-    }
-    public int addNewSymbol(String str, int hashcode) {
-        int hc = hashcode % HASHTABLE_SIZE;
-        int[] bucket = fSymbolTable[hc];
-        int chunk;
-        int index;
-        int stringIndex;
-        if (fStringFreeList != -1) {
-            stringIndex = fStringFreeList;
-            chunk = stringIndex >> CHUNK_SHIFT;
-            index = stringIndex & CHUNK_MASK;
-            fStringFreeList = fOffset[chunk][index];
-        } else {
-            stringIndex = fStringCount++;
-            chunk = stringIndex >> CHUNK_SHIFT;
-            index = stringIndex & CHUNK_MASK;
-            ensureCapacity(chunk, index);
-        }
-        int slen = str.length();
-        fString[chunk][index] = str;
-        fStringProducer[chunk][index] = null;
-        fOffset[chunk][index] = -1;
-        fLength[chunk][index] = slen;
-        fCharsOffset[chunk][index] = fSymbolCache.addSymbolToCache(str, slen, stringIndex);
-
-        hashSymbol(bucket, hashcode, chunk, index);
-        if (DEBUG_ADDITIONS)
-            System.err.println("addSymbolNew(" + str + ") " + stringIndex);
-        return stringIndex;
-    }
-    public int addSymbol(int stringIndex) {
-        if (stringIndex < 0 || stringIndex >= fStringCount)
-            return -1;
-        int chunk = stringIndex >> CHUNK_SHIFT;
-        int index = stringIndex & CHUNK_MASK;
-        if (fOffset[chunk][index] == -1)
-            return stringIndex;
-        String s = fString[chunk][index];
-        if (s == null) {
-            s = fStringProducer[chunk][index].toString(fOffset[chunk][index], fLength[chunk][index]);
-            fStringProducer[chunk][index].releaseString(fOffset[chunk][index], fLength[chunk][index]);
-            fString[chunk][index] = s;
-            fStringProducer[chunk][index] = null;
-        }
-        return addSymbol(s);
-    }
-    //
-    // Get characters for defined symbols
-    //
-    public class CharArrayRange {
-        public char[] chars;
-        public int offset;
-        public int length;
-    }
-    public CharArrayRange createCharArrayRange() {
-        return new CharArrayRange();
-    }
-    public void getCharArrayRange(int symbolIndex, CharArrayRange r) {
-        if (symbolIndex < 0 || symbolIndex >= fStringCount) {
-            r.chars = null;
-            r.offset = -1;
-            r.length = -1;
-            return;
-        }
-        int chunk = symbolIndex >> CHUNK_SHIFT;
-        int index = symbolIndex & CHUNK_MASK;
-        r.chars = fSymbolCache.getSymbolChars();
-        r.offset = fCharsOffset[chunk][index];
-        r.length = fLength[chunk][index];
-    }
-    public boolean equalNames(int stringIndex1, int stringIndex2) {
-        if (stringIndex1 == stringIndex2)
-            return true;
-        return false;
-    }
-    //
-    // String list support
-    //
-    private boolean ensureListCapacity(int chunk, int index) {
-        try {
-            return fStringList[chunk][index] == 0;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            if (index == 0) {
-                int[][] newInt = new int[chunk * 2][];
-                System.arraycopy(fStringList, 0, newInt, 0, chunk);
-                fStringList = newInt;
-            } else {
-                int[] newInt = new int[index * 2];
-                System.arraycopy(fStringList[chunk], 0, newInt, 0, index);
-                fStringList[chunk] = newInt;
-                return true;
-            }
-        } catch (NullPointerException ex) {
-        }
-        fStringList[chunk] = new int[INITIAL_CHUNK_SIZE];
-        return true;
-    }
-    public int startStringList() {
-        fActiveStringList = fStringListCount;
-        return fStringListCount;
-    }
-    public boolean addStringToList(int stringListIndex, int stringIndex) {
-        if (stringIndex == -1 || stringListIndex != fActiveStringList)
-            return false;
-        int chunk = fStringListCount >> CHUNK_SHIFT;
-        int index = fStringListCount & CHUNK_MASK;
-        ensureListCapacity(chunk, index);
-        fStringList[chunk][index] = stringIndex;
-        fStringListCount++;
-        return true;
-    }
-    public void finishStringList(int stringListIndex) {
-        if (stringListIndex != fActiveStringList)
-            return;
-        int chunk = fStringListCount >> CHUNK_SHIFT;
-        int index = fStringListCount & CHUNK_MASK;
-        ensureListCapacity(chunk, index);
-        fStringList[chunk][index] = -1;
-        fActiveStringList = -1;
-        fStringListCount++;
-    }
-    public int stringListLength(int stringListIndex) {
-        int chunk = stringListIndex >> CHUNK_SHIFT;
-        int index = stringListIndex & CHUNK_MASK;
-        int count = 0;
-        while (true) {
-            if (fStringList[chunk][index] == -1)
-                return count;
-            count++;
-            if (++index == CHUNK_SIZE) {
-                chunk++;
-                index = 0;
-            }
-        }
-    }
-    public boolean stringInList(int stringListIndex, int stringIndex) {
-        int chunk = stringListIndex >> CHUNK_SHIFT;
-        int index = stringListIndex & CHUNK_MASK;
-        while (true) {
-            if (fStringList[chunk][index] == stringIndex)
-                return true;
-            if (fStringList[chunk][index] == -1)
-                return false;
-            if (++index == CHUNK_SIZE) {
-                chunk++;
-                index = 0;
-            }
-        }
-    }
-    public String stringListAsString(int stringListIndex) {
-        int chunk = stringListIndex >> CHUNK_SHIFT;
-        int index = stringListIndex & CHUNK_MASK;
-        StringBuffer sb = new StringBuffer();
-        char sep = '(';
-        while (fStringList[chunk][index] != -1) {
-            sb.append(sep);
-            sep = '|';
-            sb.append(toString(fStringList[chunk][index]));
-            if (++index == CHUNK_SIZE) {
-                chunk++;
-                index = 0;
-            }
-        }
-        if (sep == '|')
-            sb.append(')');
-        return sb.toString();
-    }
-    public int[] stringListAsIntArray(int stringListIndex) {
-        int chunk = stringListIndex >> CHUNK_SHIFT;
-        int index = stringListIndex & CHUNK_MASK;
-        int len = stringListLength(stringListIndex);
-
-        int[] ia = new int[len];
-        for (int i=0; i<len; i++) {
-            ia[i] = fStringList[chunk][index];
-            if (++index == CHUNK_SIZE) {
-                chunk++;
-                index = 0;
-            }
-        }
-        return ia;
-    }
-    //
-    //
-    //
-    private void releaseStringInternal(int chunk, int index) {
-        fString[chunk][index] = null;
-        fStringProducer[chunk][index] = null;
-        fLength[chunk][index] = 0;
-        //
-        // REVISIT - not synchronized.
-        //
-        fOffset[chunk][index] = fStringFreeList;
-        int offset = (chunk << CHUNK_SHIFT) + index;
-        fStringFreeList = offset;
-    }
-    //
-    //
-    //
-    public void releaseString(int stringIndex) {
-        if (stringIndex < 0 || stringIndex >= fStringCount)
-            return;
-        int chunk = stringIndex >> CHUNK_SHIFT;
-        int index = stringIndex & CHUNK_MASK;
-        if (fOffset[chunk][index] != -1) {
-            if (fStringProducer[chunk][index] != null)
-                fStringProducer[chunk][index].releaseString(fOffset[chunk][index], fLength[chunk][index]);
-            releaseStringInternal(chunk, index);
-        }
-    }
-    //
-    // Get String value.  Cache the result.
-    //
-    public String toString(int stringIndex) {
-        if (stringIndex >= 0 && stringIndex < fString[0].length) {
-            String result = fString[0][stringIndex];
-            if (result != null) {
-                return result;
-            }
-        }
-
-        if (stringIndex < 0 || stringIndex >= fStringCount)
-            return null;
-        int chunk = stringIndex >> CHUNK_SHIFT;
-        int index = stringIndex & CHUNK_MASK;
-        String s = fString[chunk][index];
-        if (s != null)
-            return s;
-        s = fStringProducer[chunk][index].toString(fOffset[chunk][index], fLength[chunk][index]);
-        fStringProducer[chunk][index].releaseString(fOffset[chunk][index], fLength[chunk][index]);
-        fString[chunk][index] = s;
-        fStringProducer[chunk][index] = null;
-        return s;
-    }
-    //
-    //
-    //
-    public String orphanString(int stringIndex) {
-        if (stringIndex < 0 || stringIndex >= fStringCount)
-            return null;
-        int chunk = stringIndex >> CHUNK_SHIFT;
-        int index = stringIndex & CHUNK_MASK;
-        String s = fString[chunk][index];
-        if (s == null) {
-            s = fStringProducer[chunk][index].toString(fOffset[chunk][index], fLength[chunk][index]);
-            fStringProducer[chunk][index].releaseString(fOffset[chunk][index], fLength[chunk][index]);
-            releaseStringInternal(chunk, index);
-        } else if (fOffset[chunk][index] != -1) {
-            releaseStringInternal(chunk, index);
-        }
-        return s;
-    }
-}
diff --git a/src/org/apache/xerces/utils/SymbolCache.java b/src/org/apache/xerces/utils/SymbolCache.java
deleted file mode 100644
index 8d5e17e..0000000
--- a/src/org/apache/xerces/utils/SymbolCache.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-/**
- *
- * @version
- */
-public final class SymbolCache {
-    //
-    // Symbol Cache
-    //
-    public static final int CHAR_OFFSET = 0;
-    public static final int INDEX_OFFSET = 1;
-    public static final int NEXT_OFFSET = 2;
-    public static final int CACHE_RECORD_SIZE = 3;
-    //
-    public static final int INITIAL_CACHE_RECORD_COUNT = 4; // start with 4 entries per level
-    //
-    public char[] fSymbolChars = new char[8192];
-    public int fSymbolCharsOffset = 0;
-    public int[][] fCacheLines = new int[8][];
-    public int fCacheLineCount = 0;
-    //
-    //
-    //
-    public SymbolCache() {
-        fCacheLines[fCacheLineCount++] = new int[1+(INITIAL_CACHE_RECORD_COUNT*CACHE_RECORD_SIZE)];
-    }
-    public void reset() {
-        fSymbolCharsOffset = 0;
-        fCacheLineCount = 0;
-        fCacheLines[fCacheLineCount++] = new int[1+(INITIAL_CACHE_RECORD_COUNT*CACHE_RECORD_SIZE)];
-    }
-    //
-    //
-    //
-    public char[] getSymbolChars() {
-        return fSymbolChars;
-    }
-    //
-    // Symbol interfaces
-    //
-    public String createSymbol(int symbolHandle, int startOffset, int entry, int[] entries, int offset) {
-        int slen = fSymbolCharsOffset - startOffset;
-        String str = new String(fSymbolChars, startOffset, slen);
-        try {
-            entries[offset + SymbolCache.INDEX_OFFSET] = symbolHandle;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            throw new RuntimeException("UTL001 untested");
-        }
-        return str;
-    }
-    public int addSymbolToCache(String str, int slen, int symbolHandle) {
-        int charsOffset = fSymbolCharsOffset;
-        if (slen == 0) // EMPTY_STRING cannot be a legal "symbol"
-            return charsOffset;
-        int strIndex = 0;
-        char ch = str.charAt(strIndex++);
-        try {
-            fSymbolChars[fSymbolCharsOffset] = ch;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            char[] newChars = new char[fSymbolChars.length * 2];
-            System.arraycopy(fSymbolChars, 0, newChars, 0, fSymbolChars.length);
-            fSymbolChars = newChars;
-            fSymbolChars[fSymbolCharsOffset] = ch;
-        }
-        fSymbolCharsOffset++;
-        int entry = 0;
-        int[] entries = fCacheLines[entry];
-        int count = entries[0];
-        int i = 0;
-        int offset = 1;
-        while (true) {
-            if (i == count)
-                break;
-            if (entries[offset + CHAR_OFFSET] != ch) {
-                i++;
-                offset += CACHE_RECORD_SIZE;
-                continue;
-            }
-            if (strIndex == slen) {
-                if (entries[offset + INDEX_OFFSET] != -1) {
-                    // How did we miss this during lookup ?
-                    throw new RuntimeException("addSymbolToCache");
-                }
-                entries[offset + INDEX_OFFSET] = symbolHandle;
-                return charsOffset;
-            }
-            ch = str.charAt(strIndex++);
-            try {
-                fSymbolChars[fSymbolCharsOffset] = ch;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                char[] newChars = new char[fSymbolChars.length * 2];
-                System.arraycopy(fSymbolChars, 0, newChars, 0, fSymbolChars.length);
-                fSymbolChars = newChars;
-                fSymbolChars[fSymbolCharsOffset] = ch;
-            }
-            fSymbolCharsOffset++;
-            entry = entries[offset + NEXT_OFFSET];
-            try {
-                entries = fCacheLines[entry];
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                if (entry == -1) {
-                    entry = fCacheLineCount++;
-                    entries[offset + NEXT_OFFSET] = entry;
-                    entries = new int[1+(INITIAL_CACHE_RECORD_COUNT*CACHE_RECORD_SIZE)];
-                    try {
-                        fCacheLines[entry] = entries;
-                    } catch (ArrayIndexOutOfBoundsException ex2) {
-                        int[][] newCache = new int[entry * 2][];
-                        System.arraycopy(fCacheLines, 0, newCache, 0, entry);
-                        fCacheLines = newCache;
-                        fCacheLines[entry] = entries;
-                    }
-                } else {
-                    entries = fCacheLines[entry];
-                    throw new RuntimeException("UTL001 untested");
-                }
-            }
-            count = entries[0];
-            i = 0;
-            offset = 1;
-        }
-        while (true) {
-            entries[0]++;
-            try {
-                entries[offset + CHAR_OFFSET] = ch;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                int newSize = 1 + ((offset - 1) * 2);
-                int[] newEntries = new int[newSize];
-                System.arraycopy(entries, 0, newEntries, 0, offset);
-                fCacheLines[entry] = entries = newEntries;
-                entries[offset + CHAR_OFFSET] = ch;
-            }
-            if (strIndex == slen) {
-                entries[offset + INDEX_OFFSET] = symbolHandle;
-                entries[offset + NEXT_OFFSET] = -1;
-                break;
-            }
-            entry = fCacheLineCount++;
-            entries[offset + INDEX_OFFSET] = -1;
-            entries[offset + NEXT_OFFSET] = entry;
-            entries = new int[1+(INITIAL_CACHE_RECORD_COUNT*CACHE_RECORD_SIZE)];
-            try {
-                fCacheLines[entry] = entries;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                int[][] newCache = new int[entry * 2][];
-                System.arraycopy(fCacheLines, 0, newCache, 0, entry);
-                fCacheLines = newCache;
-                fCacheLines[entry] = entries;
-            }
-            offset = 1;
-            ch = str.charAt(strIndex++);
-            try {
-                fSymbolChars[fSymbolCharsOffset] = ch;
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                char[] newChars = new char[fSymbolChars.length * 2];
-                System.arraycopy(fSymbolChars, 0, newChars, 0, fSymbolChars.length);
-                fSymbolChars = newChars;
-                fSymbolChars[fSymbolCharsOffset] = ch;
-            }
-            fSymbolCharsOffset++;
-        }
-        return charsOffset;
-    }
-    public void updateCacheLine(int charsOffset, int totalMisses, int length) {
-//System.err.println("found symbol " + toString(symbolIndex) + " after " + totalMisses + " total misses (" + (totalMisses/length) + " misses per character).");
-        int entry = 0;
-        int[] entries = fCacheLines[0];
-        int ch = fSymbolChars[charsOffset++];
-        int count = entries[0];
-        int offset = 1 + ((count - 1) * CACHE_RECORD_SIZE);
-        int misses = 0;
-        while (true) {
-            if (ch != entries[offset + CHAR_OFFSET]) {
-                offset -= CACHE_RECORD_SIZE;
-                misses++;
-                continue;
-            }
-            if (misses > 4) {
-                int symIndex = entries[offset + INDEX_OFFSET];
-                int nextIndex = entries[offset + NEXT_OFFSET];
-                System.arraycopy(entries, offset + CACHE_RECORD_SIZE, entries, offset, misses * CACHE_RECORD_SIZE);
-                offset = 1 + ((count - 1) * CACHE_RECORD_SIZE);
-                entries[offset + CHAR_OFFSET] = ch;
-                entries[offset + INDEX_OFFSET] = symIndex;
-                entries[offset + NEXT_OFFSET] = nextIndex;
-            }
-            if (--length == 0)
-                break;
-            entry = entries[offset + NEXT_OFFSET];
-            entries = fCacheLines[entry];
-            ch = fSymbolChars[charsOffset++];
-            count = entries[0];
-            offset = 1 + ((count - 1) * CACHE_RECORD_SIZE);
-            misses = 0;
-        }
-    }
-}
diff --git a/src/org/apache/xerces/utils/URI.java b/src/org/apache/xerces/utils/URI.java
deleted file mode 100644
index aa1ceaa..0000000
--- a/src/org/apache/xerces/utils/URI.java
+++ /dev/null
@@ -1,1394 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, iClick Inc., 
- * http://www.apache.org.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-import java.io.IOException;
-import java.io.Serializable;
-
-/**********************************************************************
-* A class to represent a Uniform Resource Identifier (URI). This class
-* is designed to handle the parsing of URIs and provide access to 
-* the various components (scheme, host, port, userinfo, path, query
-* string and fragment) that may constitute a URI. 
-* <p>
-* Parsing of a URI specification is done according to the URI 
-* syntax described in RFC 2396 
-* <http://www.ietf.org/rfc/rfc2396.txt?number=2396>. Every URI consists 
-* of a scheme, followed by a colon (':'), followed by a scheme-specific
-* part. For URIs that follow the "generic URI" syntax, the scheme-
-* specific part begins with two slashes ("//") and may be followed
-* by an authority segment (comprised of user information, host, and 
-* port), path segment, query segment and fragment. Note that RFC 2396
-* no longer specifies the use of the parameters segment and excludes
-* the "user:password" syntax as part of the authority segment. If 
-* "user:password" appears in a URI, the entire user/password string
-* is stored as userinfo.
-* <p>
-* For URIs that do not follow the "generic URI" syntax (e.g. mailto),
-* the entire scheme-specific part is treated as the "path" portion
-* of the URI.
-* <p>
-* Note that, unlike the java.net.URL class, this class does not provide
-* any built-in network access functionality nor does it provide any 
-* scheme-specific functionality (for example, it does not know a 
-* default port for a specific scheme). Rather, it only knows the 
-* grammar and basic set of operations that can be applied to a URI.
-*
-* @version  $Id$
-*
-**********************************************************************/
- public class URI implements Serializable {
-
-  /*******************************************************************
-  * MalformedURIExceptions are thrown in the process of building a URI
-  * or setting fields on a URI when an operation would result in an 
-  * invalid URI specification. 
-  *
-  ********************************************************************/
-  public static class MalformedURIException extends IOException {
-
-   /******************************************************************
-    * Constructs a <code>MalformedURIException</code> with no specified
-    * detail message.
-    ******************************************************************/
-    public MalformedURIException() {
-      super();
-    }
-
-    /*****************************************************************
-    * Constructs a <code>MalformedURIException</code> with the 
-    * specified detail message. 
-    *
-    * @param p_msg the detail message.
-    ******************************************************************/
-    public MalformedURIException(String p_msg) {
-      super(p_msg);
-    }
-  }
-
-  /** reserved characters */
-  private static final String RESERVED_CHARACTERS = ";/?:@&=+$,";
-
-  /** URI punctuation mark characters - these, combined with 
-      alphanumerics, constitute the "unreserved" characters */
-  private static final String MARK_CHARACTERS = "-_.!~*'() ";
-
-  /** scheme can be composed of alphanumerics and these characters */
-  private static final String SCHEME_CHARACTERS = "+-.";
-
-  /** userinfo can be composed of unreserved, escaped and these 
-      characters */
-  private static final String USERINFO_CHARACTERS = ";:&=+$,";
-
-  /** Stores the scheme (usually the protocol) for this URI. */
-  private String m_scheme = null;
-
-  /** If specified, stores the userinfo for this URI; otherwise null */
-  private String m_userinfo = null;
-
-  /** If specified, stores the host for this URI; otherwise null */
-  private String m_host = null;
-
-  /** If specified, stores the port for this URI; otherwise -1 */
-  private int m_port = -1;
-
-  /** If specified, stores the path for this URI; otherwise null */
-  private String m_path = null;
-
-  /** If specified, stores the query string for this URI; otherwise 
-      null.  */
-  private String m_queryString = null;
-
-  /** If specified, stores the fragment for this URI; otherwise null */
-  private String m_fragment = null;
-
-  private static boolean DEBUG = false;
-
-  /**
-  * Construct a new and uninitialized URI.
-  */
-  public URI() {
-  }
-
- /**
-  * Construct a new URI from another URI. All fields for this URI are 
-  * set equal to the fields of the URI passed in.
-  *
-  * @param p_other the URI to copy (cannot be null)
-  */
-  public URI(URI p_other) {
-    initialize(p_other);
-  }
-
- /**
-  * Construct a new URI from a URI specification string. If the 
-  * specification follows the "generic URI" syntax, (two slashes 
-  * following the first colon), the specification will be parsed 
-  * accordingly - setting the scheme, userinfo, host,port, path, query
-  * string and fragment fields as necessary. If the specification does 
-  * not follow the "generic URI" syntax, the specification is parsed 
-  * into a scheme and scheme-specific part (stored as the path) only.
-  *
-  * @param p_uriSpec the URI specification string (cannot be null or
-  *                  empty)
-  *
-  * @exception MalformedURIException if p_uriSpec violates any syntax
-  *                                   rules
-  */
-  public URI(String p_uriSpec) throws MalformedURIException {
-    this((URI)null, p_uriSpec);
-  }
-
- /**
-  * Construct a new URI from a base URI and a URI specification string.
-  * The URI specification string may be a relative URI. 
-  *
-  * @param p_base the base URI (cannot be null if p_uriSpec is null or
-  *               empty)
-  * @param p_uriSpec the URI specification string (cannot be null or
-  *                  empty if p_base is null)
-  *
-  * @exception MalformedURIException if p_uriSpec violates any syntax
-  *                                  rules
-  */
-  public URI(URI p_base, String p_uriSpec) throws MalformedURIException {
-    initialize(p_base, p_uriSpec);
-  }
-
- /**
-  * Construct a new URI that does not follow the generic URI syntax.
-  * Only the scheme and scheme-specific part (stored as the path) are
-  * initialized.
-  *
-  * @param p_scheme the URI scheme (cannot be null or empty)
-  * @param p_schemeSpecificPart the scheme-specific part (cannot be
-  *                             null or empty)
-  *
-  * @exception MalformedURIException if p_scheme violates any 
-  *                                  syntax rules
-  */
-  public URI(String p_scheme, String p_schemeSpecificPart) 
-             throws MalformedURIException {
-    if (p_scheme == null || p_scheme.trim().length() == 0) {
-      throw new MalformedURIException(
-            "Cannot construct URI with null/empty scheme!");
-    }
-    if (p_schemeSpecificPart == null || 
-        p_schemeSpecificPart.trim().length() == 0) {
-      throw new MalformedURIException(
-          "Cannot construct URI with null/empty scheme-specific part!");
-    }
-    setScheme(p_scheme);
-    setPath(p_schemeSpecificPart);
-  }
-
- /**
-  * Construct a new URI that follows the generic URI syntax from its
-  * component parts. Each component is validated for syntax and some
-  * basic semantic checks are performed as well.  See the individual
-  * setter methods for specifics.
-  *
-  * @param p_scheme the URI scheme (cannot be null or empty)
-  * @param p_host the hostname or IPv4 address for the URI
-  * @param p_path the URI path - if the path contains '?' or '#',
-  *               then the query string and/or fragment will be
-  *               set from the path; however, if the query and 
-  *               fragment are specified both in the path and as 
-  *               separate parameters, an exception is thrown
-  * @param p_queryString the URI query string (cannot be specified
-  *                      if path is null)
-  * @param p_fragment the URI fragment (cannot be specified if path
-  *                   is null)
-  *
-  * @exception MalformedURIException if any of the parameters violates 
-  *                                  syntax rules or semantic rules
-  */
-  public URI(String p_scheme, String p_host, String p_path,
-             String p_queryString, String p_fragment) 
-         throws MalformedURIException {
-    this(p_scheme, null, p_host, -1, p_path, p_queryString, p_fragment);
-  }
-
- /**
-  * Construct a new URI that follows the generic URI syntax from its
-  * component parts. Each component is validated for syntax and some
-  * basic semantic checks are performed as well.  See the individual
-  * setter methods for specifics.
-  *
-  * @param p_scheme the URI scheme (cannot be null or empty)
-  * @param p_userinfo the URI userinfo (cannot be specified if host 
-  *                   is null)
-  * @param p_host the hostname or IPv4 address for the URI
-  * @param p_port the URI port (may be -1 for "unspecified"; cannot 
-  *               be specified if host is null)
-  * @param p_path the URI path - if the path contains '?' or '#',
-  *               then the query string and/or fragment will be
-  *               set from the path; however, if the query and 
-  *               fragment are specified both in the path and as 
-  *               separate parameters, an exception is thrown
-  * @param p_queryString the URI query string (cannot be specified
-  *                      if path is null)
-  * @param p_fragment the URI fragment (cannot be specified if path
-  *                   is null)
-  *
-  * @exception MalformedURIException if any of the parameters violates 
-  *                                  syntax rules or semantic rules
-  */
-  public URI(String p_scheme, String p_userinfo, 
-             String p_host, int p_port, String p_path,
-             String p_queryString, String p_fragment) 
-         throws MalformedURIException {
-    if (p_scheme == null || p_scheme.trim().length() == 0) {
-      throw new MalformedURIException("Scheme is required!");
-    }
-
-    if (p_host == null) {
-      if (p_userinfo != null) {
-        throw new MalformedURIException(
-             "Userinfo may not be specified if host is not specified!");
-      }
-      if (p_port != -1) {
-        throw new MalformedURIException(      
-             "Port may not be specified if host is not specified!");
-      }
-    }
-
-    if (p_path != null) { 
-      if (p_path.indexOf('?') != -1 && p_queryString != null) {
-        throw new MalformedURIException(
-          "Query string cannot be specified in path and query string!");
-      }
-
-      if (p_path.indexOf('#') != -1 && p_fragment != null) {
-        throw new MalformedURIException(
-          "Fragment cannot be specified in both the path and fragment!");
-      }
-    }
-
-    setScheme(p_scheme);
-    setHost(p_host);
-    setPort(p_port);
-    setUserinfo(p_userinfo);
-    setPath(p_path);
-    setQueryString(p_queryString);
-    setFragment(p_fragment);
-  }
-
- /**
-  * Initialize all fields of this URI from another URI.
-  *
-  * @param p_other the URI to copy (cannot be null)
-  */
-  private void initialize(URI p_other) {
-    m_scheme = p_other.getScheme();
-    m_userinfo = p_other.getUserinfo();
-    m_host = p_other.getHost();
-    m_port = p_other.getPort();
-    m_path = p_other.getPath();
-    m_queryString = p_other.getQueryString();
-    m_fragment = p_other.getFragment();
-  }
-
- /**
-  * Initializes this URI from a base URI and a URI specification string.
-  * See RFC 2396 Section 4 and Appendix B for specifications on parsing
-  * the URI and Section 5 for specifications on resolving relative URIs
-  * and relative paths.
-  *
-  * @param p_base the base URI (may be null if p_uriSpec is an absolute
-  *               URI)
-  * @param p_uriSpec the URI spec string which may be an absolute or
-  *                  relative URI (can only be null/empty if p_base
-  *                  is not null)
-  *
-  * @exception MalformedURIException if p_base is null and p_uriSpec
-  *                                  is not an absolute URI or if
-  *                                  p_uriSpec violates syntax rules 
-  */
-  private void initialize(URI p_base, String p_uriSpec) 
-                         throws MalformedURIException {
-    if (p_base == null && 
-        (p_uriSpec == null || p_uriSpec.trim().length() == 0)) {
-      throw new MalformedURIException(
-                  "Cannot initialize URI with empty parameters.");
-      }
-
-    // just make a copy of the base if spec is empty
-    if (p_uriSpec == null || p_uriSpec.trim().length() == 0) {
-      initialize(p_base);
-      return;
-    }
-
-    String uriSpec = p_uriSpec.trim();
-    int uriSpecLen = uriSpec.length();
-    int index = 0;
-
-    // check for scheme
-    if (uriSpec.indexOf(':') == -1) {
-      int fragmentIdx = uriSpec.indexOf('#');
-      if (p_base == null && fragmentIdx != 0 ) {//A standalone base is a valid URI according to spec
-        throw new MalformedURIException("No scheme found in URI.");
-      }
-    }
-    else {
-      initializeScheme(uriSpec);
-      index = m_scheme.length()+1;
-    }
-
-    // two slashes means generic URI syntax, so we get the authority
-    if (((index+1) < uriSpecLen) && 
-        (uriSpec.substring(index).startsWith("//"))) {
-      index += 2;
-      int startPos = index;
-
-      // get authority - everything up to path, query or fragment
-      char testChar = '\0';
-      while (index < uriSpecLen) {
-        testChar = uriSpec.charAt(index);
-        if (testChar == '/' || testChar == '?' || testChar == '#') {
-          break;
-        }
-        index++;
-      }
-
-      // if we found authority, parse it out, otherwise we set the
-      // host to empty string
-      if (index > startPos) {
-        initializeAuthority(uriSpec.substring(startPos, index));
-      }
-      else {
-        m_host = "";
-      }
-    }
-
-    initializePath(uriSpec.substring(index));
-
-    // Resolve relative URI to base URI - see RFC 2396 Section 5.2
-    // In some cases, it might make more sense to throw an exception
-    // (when scheme is specified is the string spec and the base URI
-    // is also specified, for example), but we're just following the
-    // RFC specifications 
-    if (p_base != null) {
-
-      // check to see if this is the current doc - RFC 2396 5.2 #2
-      // note that this is slightly different from the RFC spec in that
-      // we don't include the check for query string being null
-      // - this handles cases where the urispec is just a query
-      // string or a fragment (e.g. "?y" or "#s") - 
-      // see <http://www.ics.uci.edu/~fielding/url/test1.html> which
-      // identified this as a bug in the RFC
-      if (m_path.length() == 0 && m_scheme == null && 
-          m_host == null) {
-        m_scheme = p_base.getScheme();
-        m_userinfo = p_base.getUserinfo();
-        m_host = p_base.getHost();
-        m_port = p_base.getPort();
-        m_path = p_base.getPath();
-
-        if (m_queryString == null) {
-          m_queryString = p_base.getQueryString();
-        }
-        return;
-      }
-
-      // check for scheme - RFC 2396 5.2 #3
-      // if we found a scheme, it means absolute URI, so we're done
-      if (m_scheme == null) {
-        m_scheme = p_base.getScheme();
-      }
-      else {
-        return;
-      }
-
-      // check for authority - RFC 2396 5.2 #4
-      // if we found a host, then we've got a network path, so we're done
-      if (m_host == null) {
-        m_userinfo = p_base.getUserinfo();
-        m_host = p_base.getHost();
-        m_port = p_base.getPort();
-      }
-      else {
-        return;
-      }
-
-      // check for absolute path - RFC 2396 5.2 #5
-      if (m_path.length() > 0 && 
-          m_path.startsWith("/")) {
-        return;
-      }
-
-      // if we get to this point, we need to resolve relative path
-      // RFC 2396 5.2 #6
-      String path = new String();
-      String basePath = p_base.getPath();
-
-      // 6a - get all but the last segment of the base URI path
-      if (basePath != null) {
-        int lastSlash = basePath.lastIndexOf('/');
-        if (lastSlash != -1) {
-          path = basePath.substring(0, lastSlash+1);
-        }
-      }
-
-      // 6b - append the relative URI path
-      path = path.concat(m_path);
-
-      // 6c - remove all "./" where "." is a complete path segment
-      index = -1;
-      while ((index = path.indexOf("/./")) != -1) {
-        path = path.substring(0, index+1).concat(path.substring(index+3));
-      }
-
-      // 6d - remove "." if path ends with "." as a complete path segment
-      if (path.endsWith("/.")) {
-        path = path.substring(0, path.length()-1);
-      }
-
-      // 6e - remove all "<segment>/../" where "<segment>" is a complete 
-      // path segment not equal to ".."
-      index = -1;
-      int segIndex = -1;
-      String tempString = null;
-
-      while ((index = path.indexOf("/../")) > 0) {
-        tempString = path.substring(0, path.indexOf("/../"));
-        segIndex = tempString.lastIndexOf('/');
-        if (segIndex != -1) {
-          if (!tempString.substring(segIndex++).equals("..")) {
-            path = path.substring(0, segIndex).concat(path.substring(index+4));
-           }
-        }
-      }
-
-      // 6f - remove ending "<segment>/.." where "<segment>" is a 
-      // complete path segment
-      if (path.endsWith("/..")) {
-        tempString = path.substring(0, path.length()-3);
-        segIndex = tempString.lastIndexOf('/');
-        if (segIndex != -1) {
-          path = path.substring(0, segIndex+1);
-        }
-      }
-      m_path = path;
-    }
-  }
-
- /**
-  * Initialize the scheme for this URI from a URI string spec.
-  *
-  * @param p_uriSpec the URI specification (cannot be null)
-  *
-  * @exception MalformedURIException if URI does not have a conformant
-  *                                  scheme
-  */
-  private void initializeScheme(String p_uriSpec) 
-                 throws MalformedURIException {
-    int uriSpecLen = p_uriSpec.length();
-    int index = 0;
-    String scheme = null;
-    char testChar = '\0';
-
-    while (index < uriSpecLen) {
-      testChar = p_uriSpec.charAt(index);
-      if (testChar == ':' || testChar == '/' || 
-          testChar == '?' || testChar == '#') {
-        break;
-      }
-      index++;
-    }
-    scheme = p_uriSpec.substring(0, index);
-
-    if (scheme.length() == 0) {
-      throw new MalformedURIException("No scheme found in URI.");
-    }
-    else {
-      setScheme(scheme);
-    }
-  }
-
- /**
-  * Initialize the authority (userinfo, host and port) for this 
-  * URI from a URI string spec.
-  *
-  * @param p_uriSpec the URI specification (cannot be null)
-  *
-  * @exception MalformedURIException if p_uriSpec violates syntax rules
-  */
-  private void initializeAuthority(String p_uriSpec) 
-                 throws MalformedURIException {
-    int index = 0;
-    int start = 0;
-    int end = p_uriSpec.length();
-    char testChar = '\0';
-    String userinfo = null;
-
-    // userinfo is everything up @
-    if (p_uriSpec.indexOf('@', start) != -1) {
-      while (index < end) {
-        testChar = p_uriSpec.charAt(index);
-        if (testChar == '@') {
-          break;
-        }
-        index++;
-      }
-      userinfo = p_uriSpec.substring(start, index);
-      index++;
-    }
-
-    // host is everything up to ':'
-    String host = null;
-    start = index;
-    while (index < end) { 
-      testChar = p_uriSpec.charAt(index);
-      if (testChar == ':') {
-        break;
-      }
-      index++;
-    }
-    host = p_uriSpec.substring(start, index);
-    int port = -1;
-    if (host.length() > 0) {
-      // port
-      if (testChar == ':') {
-        index++;
-        start = index;
-        while (index < end) {
-          index++;
-        }
-        String portStr = p_uriSpec.substring(start, index);
-        if (portStr.length() > 0) {
-          for (int i = 0; i < portStr.length(); i++) {
-            if (!isDigit(portStr.charAt(i))) {
-              throw new MalformedURIException(
-                   portStr + 
-                   " is invalid. Port should only contain digits!");
-            }
-          } 
-          try {
-            port = Integer.parseInt(portStr);
-          }
-          catch (NumberFormatException nfe) {
-            // can't happen
-          }
-        }
-      }
-    }
-    setHost(host);
-    setPort(port);
-    setUserinfo(userinfo);
-  }
-
- /**
-  * Initialize the path for this URI from a URI string spec.
-  *
-  * @param p_uriSpec the URI specification (cannot be null)
-  *
-  * @exception MalformedURIException if p_uriSpec violates syntax rules
-  */
-  private void initializePath(String p_uriSpec) 
-                 throws MalformedURIException {
-    if (p_uriSpec == null) {
-      throw new MalformedURIException(
-                "Cannot initialize path from null string!");
-    }
-
-    int index = 0;
-    int start = 0;
-    int end = p_uriSpec.length();
-    char testChar = '\0';
-
-    // path - everything up to query string or fragment
-    while (index < end) {
-      testChar = p_uriSpec.charAt(index);
-      if (testChar == '?' || testChar == '#') {
-        break;
-      }
-      // check for valid escape sequence
-      if (testChar == '%') { 
-         if (index+2 >= end ||
-            !isHex(p_uriSpec.charAt(index+1)) ||
-            !isHex(p_uriSpec.charAt(index+2))) {
-          throw new MalformedURIException(
-                "Path contains invalid escape sequence!");
-         }
-      }
-      else if (!isReservedCharacter(testChar) && 
-               !isUnreservedCharacter(testChar)) {
-        throw new MalformedURIException(
-                  "Path contains invalid character: " + testChar);
-      }
-      index++;
-    }
-    m_path = p_uriSpec.substring(start, index);
-
-    // query - starts with ? and up to fragment or end
-    if (testChar == '?') { 
-      index++;
-      start = index;
-      while (index < end) {
-        testChar = p_uriSpec.charAt(index);
-        if (testChar == '#') {
-          break;
-        }
-        if (testChar == '%') { 
-           if (index+2 >= end ||
-              !isHex(p_uriSpec.charAt(index+1)) ||
-              !isHex(p_uriSpec.charAt(index+2))) {
-            throw new MalformedURIException(
-                    "Query string contains invalid escape sequence!");
-           }
-        }
-        else if (!isReservedCharacter(testChar) && 
-                 !isUnreservedCharacter(testChar)) {
-          throw new MalformedURIException(
-                "Query string contains invalid character:" + testChar);
-        }
-        index++;
-      }
-      m_queryString = p_uriSpec.substring(start, index);
-    }
-
-    // fragment - starts with #
-    if (testChar == '#') { 
-      index++;
-      start = index;
-      while (index < end) {
-        testChar = p_uriSpec.charAt(index);
-
-        if (testChar == '%') { 
-           if (index+2 >= end ||
-              !isHex(p_uriSpec.charAt(index+1)) ||
-              !isHex(p_uriSpec.charAt(index+2))) {
-            throw new MalformedURIException(
-                    "Fragment contains invalid escape sequence!");
-           }
-        }
-        else if (!isReservedCharacter(testChar) && 
-                 !isUnreservedCharacter(testChar)) {
-          throw new MalformedURIException(
-                "Fragment contains invalid character:"+testChar);
-        }
-        index++;
-      }
-      m_fragment = p_uriSpec.substring(start, index);
-    }
-  }
-
- /**
-  * Get the scheme for this URI.
-  *
-  * @return the scheme for this URI
-  */
-  public String getScheme() {
-    return m_scheme;
-  }
-
- /**
-  * Get the scheme-specific part for this URI (everything following the
-  * scheme and the first colon). See RFC 2396 Section 5.2 for spec.
-  *
-  * @return the scheme-specific part for this URI
-  */
-  public String getSchemeSpecificPart() {
-    StringBuffer schemespec = new StringBuffer();
-
-    if (m_userinfo != null || m_host != null || m_port != -1) {
-      schemespec.append("//");
-    }
-
-    if (m_userinfo != null) {
-      schemespec.append(m_userinfo);
-      schemespec.append('@');
-    }
-
-    if (m_host != null) {
-      schemespec.append(m_host);
-    }
-
-    if (m_port != -1) {
-      schemespec.append(':');
-      schemespec.append(m_port);
-    }
-
-    if (m_path != null) {
-      schemespec.append((m_path));
-    }
-
-    if (m_queryString != null) {
-      schemespec.append('?');
-      schemespec.append(m_queryString);
-    }
-
-    if (m_fragment != null) {
-      schemespec.append('#');
-      schemespec.append(m_fragment);
-    }
-
-    return schemespec.toString();
-  }
-
- /**
-  * Get the userinfo for this URI.
-  *
-  * @return the userinfo for this URI (null if not specified).
-  */
-  public String getUserinfo() {
-    return m_userinfo;
-  }
-
-  /**
-  * Get the host for this URI.
-  *
-  * @return the host for this URI (null if not specified).
-  */
-  public String getHost() {
-    return m_host;
-  }
-
- /**
-  * Get the port for this URI.
-  *
-  * @return the port for this URI (-1 if not specified).
-  */
-  public int getPort() {
-    return m_port;
-  }
-
- /**
-  * Get the path for this URI (optionally with the query string and
-  * fragment). 
-  *
-  * @param p_includeQueryString if true (and query string is not null),
-  *                             then a "?" followed by the query string 
-  *                             will be appended 
-  * @param p_includeFragment if true (and fragment is not null),
-  *                             then a "#" followed by the fragment
-  *                             will be appended
-  *
-  * @return the path for this URI possibly including the query string
-  *         and fragment
-  */
-  public String getPath(boolean p_includeQueryString, 
-                        boolean p_includeFragment) {
-    StringBuffer pathString = new StringBuffer(m_path);
-
-    if (p_includeQueryString && m_queryString != null) {
-      pathString.append('?');
-      pathString.append(m_queryString);
-    }
-
-    if (p_includeFragment && m_fragment != null) {
-      pathString.append('#');
-      pathString.append(m_fragment);
-    }
-    return pathString.toString();
-  }
-
- /**
-  * Get the path for this URI. Note that the value returned is the path
-  * only and does not include the query string or fragment.
-  *
-  * @return the path for this URI.
-  */
-  public String getPath() {
-    return m_path;
-  }
-
- /**
-  * Get the query string for this URI.
-  *
-  * @return the query string for this URI. Null is returned if there
-  *         was no "?" in the URI spec, empty string if there was a 
-  *         "?" but no query string following it.
-  */
-  public String getQueryString() {
-    return m_queryString;
-  }
-
- /**
-  * Get the fragment for this URI.
-  *
-  * @return the fragment for this URI. Null is returned if there
-  *         was no "#" in the URI spec, empty string if there was a 
-  *         "#" but no fragment following it.
-  */
-  public String getFragment() {
-    return m_fragment;
-  }
-
- /**
-  * Set the scheme for this URI. The scheme is converted to lowercase
-  * before it is set.
-  *
-  * @param p_scheme the scheme for this URI (cannot be null)
-  *
-  * @exception MalformedURIException if p_scheme is not a conformant
-  *                                  scheme name
-  */
-  public void setScheme(String p_scheme) throws MalformedURIException {
-    if (p_scheme == null) {
-      throw new MalformedURIException(
-                "Cannot set scheme from null string!");
-    }
-    if (!isConformantSchemeName(p_scheme)) {
-      throw new MalformedURIException("The scheme is not conformant.");
-    }
-
-    m_scheme = p_scheme.toLowerCase();
-  }
-
- /**
-  * Set the userinfo for this URI. If a non-null value is passed in and 
-  * the host value is null, then an exception is thrown.
-  *
-  * @param p_userinfo the userinfo for this URI
-  *
-  * @exception MalformedURIException if p_userinfo contains invalid
-  *                                  characters
-  */
-  public void setUserinfo(String p_userinfo) throws MalformedURIException {
-    if (p_userinfo == null) {
-      m_userinfo = null;
-    }
-    else {
-      if (m_host == null) {
-        throw new MalformedURIException(
-                     "Userinfo cannot be set when host is null!");
-      }
-
-      // userinfo can contain alphanumerics, mark characters, escaped
-      // and ';',':','&','=','+','$',','
-      int index = 0;
-      int end = p_userinfo.length();
-      char testChar = '\0';
-      while (index < end) {
-        testChar = p_userinfo.charAt(index);
-        if (testChar == '%') {
-          if (index+2 >= end ||
-              !isHex(p_userinfo.charAt(index+1)) ||
-              !isHex(p_userinfo.charAt(index+2))) {
-            throw new MalformedURIException(
-                  "Userinfo contains invalid escape sequence!");
-          }
-        }
-        else if (!isUnreservedCharacter(testChar) &&
-                 USERINFO_CHARACTERS.indexOf(testChar) == -1) {
-          throw new MalformedURIException(
-                  "Userinfo contains invalid character:"+testChar);
-        }
-        index++;
-      }
-    }
-    m_userinfo = p_userinfo;
-  }
-
-  /**
-  * Set the host for this URI. If null is passed in, the userinfo
-  * field is also set to null and the port is set to -1.
-  *
-  * @param p_host the host for this URI
-  *
-  * @exception MalformedURIException if p_host is not a valid IP 
-  *                                  address or DNS hostname.
-  */
-  public void setHost(String p_host) throws MalformedURIException {
-    if (p_host == null || p_host.trim().length() == 0) {
-      m_host = p_host;
-      m_userinfo = null;
-      m_port = -1;
-    }
-    else if (!isWellFormedAddress(p_host)) {
-      throw new MalformedURIException("Host is not a well formed address!");
-    } 
-    m_host = p_host;
-  }
-
- /**
-  * Set the port for this URI. -1 is used to indicate that the port is
-  * not specified, otherwise valid port numbers are  between 0 and 65535.
-  * If a valid port number is passed in and the host field is null,
-  * an exception is thrown.
-  *
-  * @param p_port the port number for this URI
-  *
-  * @exception MalformedURIException if p_port is not -1 and not a 
-  *                                  valid port number 
-  */
-  public void setPort(int p_port) throws MalformedURIException {
-    if (p_port >= 0 && p_port <= 65535) {
-      if (m_host == null) {
-        throw new MalformedURIException(
-                      "Port cannot be set when host is null!");
-      }
-    }
-    else if (p_port != -1) {
-      throw new MalformedURIException("Invalid port number!");
-    }
-    m_port = p_port;
-  }
-
- /**
-  * Set the path for this URI. If the supplied path is null, then the
-  * query string and fragment are set to null as well. If the supplied 
-  * path includes a query string and/or fragment, these fields will be
-  * parsed and set as well. Note that, for URIs following the "generic
-  * URI" syntax, the path specified should start with a slash.
-  * For URIs that do not follow the generic URI syntax, this method 
-  * sets the scheme-specific part.
-  *
-  * @param p_path the path for this URI (may be null)
-  *
-  * @exception MalformedURIException if p_path contains invalid
-  *                                  characters
-  */
-  public void setPath(String p_path) throws MalformedURIException {
-    if (p_path == null) {
-      m_path = null;
-      m_queryString = null;
-      m_fragment = null;
-    }
-    else {
-      initializePath(p_path);
-    }
-  }
-
- /**
-  * Append to the end of the path of this URI. If the current path does
-  * not end in a slash and the path to be appended does not begin with 
-  * a slash, a slash will be appended to the current path before the 
-  * new segment is added. Also, if the current path ends in a slash
-  * and the new segment begins with a slash, the extra slash will be
-  * removed before the new segment is appended.
-  *
-  * @param p_addToPath the new segment to be added to the current path
-  *
-  * @exception MalformedURIException if p_addToPath contains syntax
-  *                                  errors
-  */
-  public void appendPath(String p_addToPath) 
-                         throws MalformedURIException {
-    if (p_addToPath == null || p_addToPath.trim().length() == 0) {
-      return;
-    }
-
-    if (!isURIString(p_addToPath)) {
-      throw new MalformedURIException(
-              "Path contains invalid character!");
-    }
-
-    if (m_path == null || m_path.trim().length() == 0) {
-      if (p_addToPath.startsWith("/")) {
-        m_path = p_addToPath;
-      }
-      else {
-        m_path = "/" + p_addToPath;
-      }
-    }
-    else if (m_path.endsWith("/")) {
-      if (p_addToPath.startsWith("/")) {
-        m_path = m_path.concat(p_addToPath.substring(1));
-      }
-      else {
-        m_path = m_path.concat(p_addToPath);
-      }
-    }
-    else {
-      if (p_addToPath.startsWith("/")) {
-        m_path = m_path.concat(p_addToPath);
-      }
-      else {
-        m_path = m_path.concat("/" + p_addToPath);
-      }
-    }
-  }
-
- /**
-  * Set the query string for this URI. A non-null value is valid only
-  * if this is an URI conforming to the generic URI syntax and 
-  * the path value is not null.
-  *
-  * @param p_queryString the query string for this URI
-  *
-  * @exception MalformedURIException if p_queryString is not null and this  
-  *                                  URI does not conform to the generic
-  *                                  URI syntax or if the path is null
-  */
-  public void setQueryString(String p_queryString) throws MalformedURIException {
-    if (p_queryString == null) {
-      m_queryString = null;
-    }
-    else if (!isGenericURI()) {
-      throw new MalformedURIException(
-              "Query string can only be set for a generic URI!");
-    }
-    else if (getPath() == null) {
-      throw new MalformedURIException(
-              "Query string cannot be set when path is null!");
-    }
-    else if (!isURIString(p_queryString)) {
-      throw new MalformedURIException(
-              "Query string contains invalid character!");
-    }
-    else {
-      m_queryString = p_queryString;
-    }
-  }
-
- /**
-  * Set the fragment for this URI. A non-null value is valid only
-  * if this is a URI conforming to the generic URI syntax and 
-  * the path value is not null.
-  *
-  * @param p_fragment the fragment for this URI
-  *
-  * @exception MalformedURIException if p_fragment is not null and this  
-  *                                  URI does not conform to the generic
-  *                                  URI syntax or if the path is null
-  */
-  public void setFragment(String p_fragment) throws MalformedURIException {
-    if (p_fragment == null) {
-      m_fragment = null;
-    }
-    else if (!isGenericURI()) {
-      throw new MalformedURIException(
-         "Fragment can only be set for a generic URI!");
-    }
-    else if (getPath() == null) {
-      throw new MalformedURIException(
-              "Fragment cannot be set when path is null!");
-    }
-    else if (!isURIString(p_fragment)) {
-      throw new MalformedURIException(
-              "Fragment contains invalid character!");
-    }
-    else {
-      m_fragment = p_fragment;
-    }
-  }
-
- /**
-  * Determines if the passed-in Object is equivalent to this URI.
-  *
-  * @param p_test the Object to test for equality.
-  *
-  * @return true if p_test is a URI with all values equal to this
-  *         URI, false otherwise
-  */
-  public boolean equals(Object p_test) {
-    if (p_test instanceof URI) {
-      URI testURI = (URI) p_test;
-      if (((m_scheme == null && testURI.m_scheme == null) ||
-           (m_scheme != null && testURI.m_scheme != null &&
-            m_scheme.equals(testURI.m_scheme))) &&
-          ((m_userinfo == null && testURI.m_userinfo == null) ||
-           (m_userinfo != null && testURI.m_userinfo != null &&
-            m_userinfo.equals(testURI.m_userinfo))) &&
-          ((m_host == null && testURI.m_host == null) ||
-           (m_host != null && testURI.m_host != null &&
-            m_host.equals(testURI.m_host))) &&
-            m_port == testURI.m_port &&
-          ((m_path == null && testURI.m_path == null) ||
-           (m_path != null && testURI.m_path != null &&
-            m_path.equals(testURI.m_path))) &&
-          ((m_queryString == null && testURI.m_queryString == null) ||
-           (m_queryString != null && testURI.m_queryString != null &&
-            m_queryString.equals(testURI.m_queryString))) &&
-          ((m_fragment == null && testURI.m_fragment == null) ||
-           (m_fragment != null && testURI.m_fragment != null &&
-            m_fragment.equals(testURI.m_fragment)))) {
-        return true;
-      }
-    }
-    return false;
-  }
-
- /**
-  * Get the URI as a string specification. See RFC 2396 Section 5.2.
-  *
-  * @return the URI string specification
-  */
-  public String toString() {
-    StringBuffer uriSpecString = new StringBuffer();
-
-    if (m_scheme != null) {
-      uriSpecString.append(m_scheme);
-      uriSpecString.append(':');
-    }
-    uriSpecString.append(getSchemeSpecificPart());
-    return uriSpecString.toString();
-  }
-
- /**
-  * Get the indicator as to whether this URI uses the "generic URI"
-  * syntax.
-  *
-  * @return true if this URI uses the "generic URI" syntax, false
-  *         otherwise
-  */
-  public boolean isGenericURI() {
-    // presence of the host (whether valid or empty) means 
-    // double-slashes which means generic uri
-    return (m_host != null);
-  }
-
- /**
-  * Determine whether a scheme conforms to the rules for a scheme name.
-  * A scheme is conformant if it starts with an alphanumeric, and 
-  * contains only alphanumerics, '+','-' and '.'.
-  *
-  * @return true if the scheme is conformant, false otherwise
-  */
-  public static boolean isConformantSchemeName(String p_scheme) {
-    if (p_scheme == null || p_scheme.trim().length() == 0) {
-      return false;
-    }
-
-    if (!isAlpha(p_scheme.charAt(0))) {
-      return false;
-    }
-
-    char testChar;
-    for (int i = 1; i < p_scheme.length(); i++) {
-      testChar = p_scheme.charAt(i);
-      if (!isAlphanum(testChar) && 
-          SCHEME_CHARACTERS.indexOf(testChar) == -1) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
- /**
-  * Determine whether a string is syntactically capable of representing
-  * a valid IPv4 address or the domain name of a network host. A valid
-  * IPv4 address consists of four decimal digit groups separated by a
-  * '.'. A hostname consists of domain labels (each of which must 
-  * begin and end with an alphanumeric but may contain '-') separated
-  & by a '.'. See RFC 2396 Section 3.2.2.
-  *
-  * @return true if the string is a syntactically valid IPv4 address 
-  *              or hostname
-  */
-  public static boolean isWellFormedAddress(String p_address) {
-    if (p_address == null) {
-      return false;
-    }
-
-    String address = p_address.trim();
-    int addrLength = address.length();
-    if (addrLength == 0 || addrLength > 255) {
-      return false;
-    }
-
-    if (address.startsWith(".") || address.startsWith("-")) {
-      return false;
-    }
-
-    // rightmost domain label starting with digit indicates IP address
-    // since top level domain label can only start with an alpha
-    // see RFC 2396 Section 3.2.2
-    int index = address.lastIndexOf('.');
-    if (address.endsWith(".")) {
-      index = address.substring(0, index).lastIndexOf('.');
-    }
-
-    if (index+1 < addrLength && isDigit(p_address.charAt(index+1))) {
-      char testChar;
-      int numDots = 0;
-
-      // make sure that 1) we see only digits and dot separators, 2) that
-      // any dot separator is preceded and followed by a digit and 
-      // 3) that we find 3 dots
-      for (int i = 0; i < addrLength; i++) {
-        testChar = address.charAt(i);
-        if (testChar == '.') {
-          if (!isDigit(address.charAt(i-1)) || 
-              (i+1 < addrLength && !isDigit(address.charAt(i+1)))) {
-            return false;
-          }
-          numDots++;
-        }
-        else if (!isDigit(testChar)) {
-          return false;
-        }
-      }
-      if (numDots != 3) {
-        return false;
-      }
-    }
-    else {
-      // domain labels can contain alphanumerics and '-"
-      // but must start and end with an alphanumeric
-      char testChar;
-  
-      for (int i = 0; i < addrLength; i++) {
-        testChar = address.charAt(i);
-        if (testChar == '.') {
-          if (!isAlphanum(address.charAt(i-1))) {
-            return false;
-          } 
-          if (i+1 < addrLength && !isAlphanum(address.charAt(i+1))) {
-            return false;
-          }
-        }
-        else if (!isAlphanum(testChar) && testChar != '-') {
-          return false;
-        }
-      }
-    }
-    return true;
-  }
-
-
- /**
-  * Determine whether a char is a digit.
-  *
-  * @return true if the char is betweeen '0' and '9', false otherwise
-  */
-  private static boolean isDigit(char p_char) {
-    return p_char >= '0' && p_char <= '9';
-  }
-
- /**
-  * Determine whether a character is a hexadecimal character.
-  *
-  * @return true if the char is betweeen '0' and '9', 'a' and 'f'
-  *         or 'A' and 'F', false otherwise
-  */
-  private static boolean isHex(char p_char) {
-    return (isDigit(p_char) || 
-            (p_char >= 'a' && p_char <= 'f') || 
-            (p_char >= 'A' && p_char <= 'F'));
-  }
-
- /**
-  * Determine whether a char is an alphabetic character: a-z or A-Z
-  *
-  * @return true if the char is alphabetic, false otherwise
-  */
-  private static boolean isAlpha(char p_char) {
-    return ((p_char >= 'a' && p_char <= 'z') || 
-            (p_char >= 'A' && p_char <= 'Z' )); 
-  }
-
- /**
-  * Determine whether a char is an alphanumeric: 0-9, a-z or A-Z
-  *
-  * @return true if the char is alphanumeric, false otherwise
-  */
-  private static boolean isAlphanum(char p_char) {
-    return (isAlpha(p_char) || isDigit(p_char)); 
-  }
-
- /**
-  * Determine whether a character is a reserved character:
-  * ';', '/', '?', ':', '@', '&', '=', '+', '$' or ',' 
-  *
-  * @return true if the string contains any reserved characters
-  */
-  private static boolean isReservedCharacter(char p_char) {
-    return RESERVED_CHARACTERS.indexOf(p_char) != -1;
-  }
-
- /**
-  * Determine whether a char is an unreserved character.
-  *
-  * @return true if the char is unreserved, false otherwise
-  */
-  private static boolean isUnreservedCharacter(char p_char) {
-    return (isAlphanum(p_char) || 
-            MARK_CHARACTERS.indexOf(p_char) != -1);
-  }
-
- /**
-  * Determine whether a given string contains only URI characters (also
-  * called "uric" in RFC 2396). uric consist of all reserved
-  * characters, unreserved characters and escaped characters.
-  *
-  * @return true if the string is comprised of uric, false otherwise
-  */
-  private static boolean isURIString(String p_uric) {
-    if (p_uric == null) {
-      return false;
-    }
-    int end = p_uric.length();
-    char testChar = '\0';
-    for (int i = 0; i < end; i++) {
-      testChar = p_uric.charAt(i);
-      if (testChar == '%') {
-        if (i+2 >= end ||
-            !isHex(p_uric.charAt(i+1)) ||
-            !isHex(p_uric.charAt(i+2))) {
-          return false;
-        }
-        else {
-          i += 2;
-          continue;
-        }
-      }
-      if (isReservedCharacter(testChar) || 
-          isUnreservedCharacter(testChar)) {
-          continue;
-      }
-      else {
-        return false;
-      }
-    }
-    return true;
-  }
-}
diff --git a/src/org/apache/xerces/utils/UTF8DataChunk.java b/src/org/apache/xerces/utils/UTF8DataChunk.java
deleted file mode 100644
index 4a20956..0000000
--- a/src/org/apache/xerces/utils/UTF8DataChunk.java
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-import org.apache.xerces.readers.XMLEntityHandler;
-import java.util.Vector;
-
-//
-//
-//
-public class UTF8DataChunk implements StringPool.StringProducer {
-    //
-    // Chunk size constants
-    //
-    public static final int CHUNK_SHIFT = 14;           // 2^14 = 16k
-    public static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
-    public static final int CHUNK_MASK = CHUNK_SIZE - 1;
-    //
-    // Public constructor (factory)
-    //
-    public static UTF8DataChunk createChunk(StringPool stringPool, UTF8DataChunk prev) {
-
-        synchronized (UTF8DataChunk.class) {
-            if (fgFreeChunks != null) {
-                UTF8DataChunk newChunk = fgFreeChunks;
-                fgFreeChunks = newChunk.fNextChunk;
-                newChunk.fNextChunk = null;
-                newChunk.init(stringPool, prev);
-                return newChunk;
-            }
-        }
-        UTF8DataChunk chunk = new UTF8DataChunk(stringPool, prev);
-        return chunk;
-    }
-    //
-    //
-    //
-    public final byte[] toByteArray() {
-        return fData;
-    }
-    //
-    //
-    //
-    public void setByteArray(byte[] data) {
-        fData = data;
-    }
-    //
-    //
-    //
-    public UTF8DataChunk nextChunk() {
-        return fNextChunk;
-    }
-    //
-    //
-    //
-    public boolean clearPreviousChunk() {
-        if (fPreviousChunk != null) {
-            fPreviousChunk.setNextChunk(null);
-            fPreviousChunk.removeRef();
-//System.err.println("[" + fPreviousChunk.fChunk + "] " + fPreviousChunk.fRefCount + " refs after clearPreviousChunk");
-//System.err.println("[" + fChunk + "] " + fRefCount + " refs after clearPreviousChunk");
-            fPreviousChunk = null;
-            return true;
-        }
-        return fChunk == 0;
-    }
-    //
-    //
-    //
-    public void releaseChunk() {
-        removeRef();
-//System.err.println("[" + fChunk + "] " + fRefCount + " refs after releaseChunk");
-    }
-    //
-    //
-    //
-    public void releaseString(int offset, int length) {
-        removeRef();
-    }
-    //
-    //
-    //
-    public String toString(int offset, int length) {
-
-        synchronized (fgTempBufferLock) {
-            int outOffset = 0;
-            UTF8DataChunk dataChunk = this;
-            int endOffset = offset + length;
-            int index = offset & CHUNK_MASK;
-            byte[] data = fData;
-            boolean skiplf = false;
-            while (offset < endOffset) {
-                int b0 = data[index++] & 0xff;
-                offset++;
-                if (index == CHUNK_SIZE && offset < endOffset) {
-                    dataChunk = dataChunk.fNextChunk;
-                    data = dataChunk.fData;
-                    index = 0;
-                }
-                if (b0 < 0x80) {
-                    if (skiplf) {
-                        skiplf = false;
-                        if (b0 == 0x0A)
-                            continue;
-                    }
-                    if (b0 == 0x0D) {
-                        b0 = 0x0A;
-                        skiplf = true;
-                    }
-                    try {
-                        fgTempBuffer[outOffset] = (char)b0;
-                        outOffset++;
-                    } catch (NullPointerException ex) {
-                        fgTempBuffer = new char[CHUNK_SIZE];
-                        fgTempBuffer[outOffset++] = (char)b0;
-                    } catch (ArrayIndexOutOfBoundsException ex) {
-                        char[] newBuffer = new char[outOffset * 2];
-                        System.arraycopy(fgTempBuffer, 0, newBuffer, 0, outOffset);
-                        fgTempBuffer = newBuffer;
-                        fgTempBuffer[outOffset++] = (char)b0;
-                    }
-                    continue;
-                }
-                int b1 = data[index++] & 0xff;
-                offset++;
-                if (index == CHUNK_SIZE && offset < endOffset) {
-                    dataChunk = dataChunk.fNextChunk;
-                    data = dataChunk.fData;
-                    index = 0;
-                }
-                if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx
-                    int ch = ((0x1f & b0)<<6) + (0x3f & b1); // yyy yyxx xxxx (0x80 to 0x7ff)
-                    try {
-                        fgTempBuffer[outOffset] = (char)ch;
-                        outOffset++;
-                    } catch (NullPointerException ex) {
-                        fgTempBuffer = new char[CHUNK_SIZE];
-                        fgTempBuffer[outOffset++] = (char)ch;
-                    } catch (ArrayIndexOutOfBoundsException ex) {
-                        char[] newBuffer = new char[outOffset * 2];
-                        System.arraycopy(fgTempBuffer, 0, newBuffer, 0, outOffset);
-                        fgTempBuffer = newBuffer;
-                        fgTempBuffer[outOffset++] = (char)ch;
-                    }
-                    continue;
-                }
-                int b2 = data[index++] & 0xff;
-                offset++;
-                if (index == CHUNK_SIZE && offset < endOffset) {
-                    dataChunk = dataChunk.fNextChunk;
-                    data = dataChunk.fData;
-                    index = 0;
-                }
-                if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-                    int ch = ((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2); // zzzz yyyy yyxx xxxx (0x800 to 0xffff)
-                    try {
-                        fgTempBuffer[outOffset] = (char)ch;
-                        outOffset++;
-                    } catch (NullPointerException ex) {
-                        fgTempBuffer = new char[CHUNK_SIZE];
-                        fgTempBuffer[outOffset++] = (char)ch;
-                    } catch (ArrayIndexOutOfBoundsException ex) {
-                        char[] newBuffer = new char[outOffset * 2];
-                        System.arraycopy(fgTempBuffer, 0, newBuffer, 0, outOffset);
-                        fgTempBuffer = newBuffer;
-                        fgTempBuffer[outOffset++] = (char)ch;
-                    }
-                    continue;
-                }
-                int b3 = data[index++] & 0xff;  // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-                offset++;
-                if (index == CHUNK_SIZE && offset < endOffset) {
-                    dataChunk = dataChunk.fNextChunk;
-                    data = dataChunk.fData;
-                    index = 0;
-                }
-                int ch = ((0x0f & b0)<<18) + ((0x3f & b1)<<12) + ((0x3f & b2)<<6) + (0x3f & b3);
-                if (ch < 0x10000) {
-                    try {
-                        fgTempBuffer[outOffset] = (char)ch;
-                        outOffset++;
-                    } catch (NullPointerException ex) {
-                        fgTempBuffer = new char[CHUNK_SIZE];
-                        fgTempBuffer[outOffset++] = (char)ch;
-                    } catch (ArrayIndexOutOfBoundsException ex) {
-                        char[] newBuffer = new char[outOffset * 2];
-                        System.arraycopy(fgTempBuffer, 0, newBuffer, 0, outOffset);
-                        fgTempBuffer = newBuffer;
-                        fgTempBuffer[outOffset++] = (char)ch;
-                    }
-                } else {
-                    char ch1 = (char)(((ch-0x00010000)>>10)+0xd800);
-                    char ch2 = (char)(((ch-0x00010000)&0x3ff)+0xdc00);
-                    try {
-                        fgTempBuffer[outOffset] = (char)ch1;
-                        outOffset++;
-                    } catch (NullPointerException ex) {
-                        fgTempBuffer = new char[CHUNK_SIZE];
-                        fgTempBuffer[outOffset++] = (char)ch1;
-                    } catch (ArrayIndexOutOfBoundsException ex) {
-                        char[] newBuffer = new char[outOffset * 2];
-                        System.arraycopy(fgTempBuffer, 0, newBuffer, 0, outOffset);
-                        fgTempBuffer = newBuffer;
-                        fgTempBuffer[outOffset++] = (char)ch1;
-                    }
-                    try {
-                        fgTempBuffer[outOffset] = (char)ch2;
-                        outOffset++;
-                    } catch (NullPointerException ex) {
-                        fgTempBuffer = new char[CHUNK_SIZE];
-                        fgTempBuffer[outOffset++] = (char)ch2;
-                    } catch (ArrayIndexOutOfBoundsException ex) {
-                        char[] newBuffer = new char[outOffset * 2];
-                        System.arraycopy(fgTempBuffer, 0, newBuffer, 0, outOffset);
-                        fgTempBuffer = newBuffer;
-                        fgTempBuffer[outOffset++] = (char)ch2;
-                    }
-                }
-            }
-            return new String(fgTempBuffer, 0, outOffset);
-        }
-    }
-    //
-    //
-    //
-    public boolean equalsString(int offset, int length, char[] strChars, int strOffset, int strLength) {
-        UTF8DataChunk dataChunk = this;
-        int endOffset = offset + length;
-        int index = offset & CHUNK_MASK;
-        byte[] data = fData;
-        boolean skiplf = false;
-        while (offset < endOffset) {
-            if (strLength-- == 0)
-                return false;
-            int b0 = data[index++] & 0xff;
-            offset++;
-            if (index == CHUNK_SIZE && offset < endOffset) {
-                dataChunk = dataChunk.fNextChunk;
-                data = dataChunk.fData;
-                index = 0;
-            }
-            if (b0 < 0x80) {
-                if (skiplf) {
-                    skiplf = false;
-                    if (b0 == 0x0A)
-                        continue;
-                }
-                if (b0 == 0x0D) {
-                    b0 = 0x0A;
-                    skiplf = true;
-                }
-                if (b0 != strChars[strOffset++])
-                    return false;
-                continue;
-            }
-            int b1 = data[index++] & 0xff;
-            offset++;
-            if (index == CHUNK_SIZE && offset < endOffset) {
-                dataChunk = dataChunk.fNextChunk;
-                data = dataChunk.fData;
-                index = 0;
-            }
-            if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx
-                int ch = ((0x1f & b0)<<6) + (0x3f & b1);
-                if (ch != strChars[strOffset++])
-                    return false;
-                continue;
-            }
-            int b2 = data[index++] & 0xff;
-            offset++;
-            if (index == CHUNK_SIZE && offset < endOffset) {
-                dataChunk = dataChunk.fNextChunk;
-                data = dataChunk.fData;
-                index = 0;
-            }
-            if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-                int ch = ((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2);
-                if (ch != strChars[strOffset++])
-                    return false;
-                continue;
-            }
-            int b3 = data[index++] & 0xff;  // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-            offset++;
-            if (index == CHUNK_SIZE && offset < endOffset) {
-                dataChunk = dataChunk.fNextChunk;
-                data = dataChunk.fData;
-                index = 0;
-            }
-            int ch = ((0x0f & b0)<<18) + ((0x3f & b1)<<12)
-                   + ((0x3f & b2)<<6) + (0x3f & b3);
-            if (ch < 0x10000) {
-                if (ch != strChars[strOffset++])
-                    return false;
-            } else {
-                if ((((ch-0x00010000)>>10)+0xd800) != strChars[strOffset++])
-                    return false;
-                if (strLength-- == 0)
-                    return false;
-                if ((((ch-0x00010000)&0x3ff)+0xdc00) != strChars[strOffset++])
-                    return false;
-            }
-        }
-        return (strLength == 0);
-    }
-    //
-    //
-    //
-    public int addString(int offset, int length) {
-        if (length == 0)
-            return StringPool.EMPTY_STRING;
-        int chunk = offset >> CHUNK_SHIFT;
-        if (chunk != fChunk) {
-            if (fPreviousChunk == null)
-                throw new RuntimeException(new ImplementationMessages().createMessage(null, ImplementationMessages.INT_PCN, 0, null));
-            return fPreviousChunk.addString(offset, length);
-        }
-        int lastChunk = (offset + length - 1) >> CHUNK_SHIFT;
-        if (chunk == lastChunk) {
-            addRef();
-            return fStringPool.addString(this, offset & CHUNK_MASK, length);
-        }
-        String str = toString(offset & CHUNK_MASK, length);
-        return fStringPool.addString(str);
-    }
-    //
-    //
-    //
-    public int addSymbol(int offset, int length, int hashcode) {
-        if (length == 0)
-            return StringPool.EMPTY_STRING;
-        int chunk = offset >> CHUNK_SHIFT;
-        if (chunk != fChunk) {
-            if (fPreviousChunk == null)
-                throw new RuntimeException(new ImplementationMessages().createMessage(null, ImplementationMessages.INT_PCN, 0, null));
-            return fPreviousChunk.addSymbol(offset, length, hashcode);
-        }
-        int lastChunk = (offset + length - 1) >> CHUNK_SHIFT;
-        int index = offset & CHUNK_MASK;
-        if (chunk == lastChunk) {
-            if (hashcode == 0) {
-                hashcode = getHashcode(index, length);
-            }
-            int symbol = fStringPool.lookupSymbol(this, index, length, hashcode);
-            if (symbol == -1) {
-                String str = toString(index, length);
-                symbol = fStringPool.addNewSymbol(str, hashcode);
-            }
-            return symbol;
-        }
-        String str = toString(index, length);
-        return fStringPool.addSymbol(str);
-    }
-    //
-    //
-    //
-    public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length) {
-        //
-        // Setup for the operation.
-        //
-        UTF8DataChunk dataChunk = chunkFor(offset);
-        int endOffset = offset + length;
-        int index = offset & CHUNK_MASK;
-        byte[] data = dataChunk.fData;
-        boolean skiplf = false;
-        while (offset < endOffset) {
-            int b0 = data[index++] & 0xff;
-            offset++;
-            if (index == CHUNK_SIZE && offset < endOffset) {
-                dataChunk = dataChunk.fNextChunk;
-                data = dataChunk.fData;
-                index = 0;
-            }
-            if (b0 < 0x80) {
-                if (skiplf) {
-                    skiplf = false;
-                    if (b0 == 0x0A)
-                        continue;
-                }
-                if (b0 == 0x0D) {
-                    b0 = 0x0A;
-                    skiplf = true;
-                }
-                charBuffer.append((char)b0);
-                continue;
-            }
-            int b1 = data[index++] & 0xff;
-            offset++;
-            if (index == CHUNK_SIZE && offset < endOffset) {
-                dataChunk = dataChunk.fNextChunk;
-                data = dataChunk.fData;
-                index = 0;
-            }
-            if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx
-                int ch = ((0x1f & b0)<<6) + (0x3f & b1);
-                charBuffer.append((char)ch); // yyy yyxx xxxx (0x80 to 0x7ff)
-                continue;
-            }
-            int b2 = data[index++] & 0xff;
-            offset++;
-            if (index == CHUNK_SIZE && offset < endOffset) {
-                dataChunk = dataChunk.fNextChunk;
-                data = dataChunk.fData;
-                index = 0;
-            }
-            if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-                int ch = ((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2);
-                charBuffer.append((char)ch); // zzzz yyyy yyxx xxxx (0x800 to 0xffff)
-                continue;
-            }
-            int b3 = data[index++] & 0xff;  // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-            offset++;
-            if (index == CHUNK_SIZE && offset < endOffset) {
-                dataChunk = dataChunk.fNextChunk;
-                data = dataChunk.fData;
-                index = 0;
-            }
-            int ch = ((0x0f & b0)<<18) + ((0x3f & b1)<<12)
-                   + ((0x3f & b2)<<6) + (0x3f & b3);
-            if (ch < 0x10000)
-                charBuffer.append((char)ch);
-            else {
-                charBuffer.append((char)(((ch-0x00010000)>>10)+0xd800));
-                charBuffer.append((char)(((ch-0x00010000)&0x3ff)+0xdc00));
-            }
-        }
-    }
-    //
-    //
-    //
-    private int getHashcode(int index, int length) {
-        int endIndex = index + length;
-        int hashcode = 0;
-        byte[] data = fData;
-        while (index < endIndex) {
-            int b0 = data[index++] & 0xff;
-            if ((b0 & 0x80) == 0) {
-                hashcode = StringHasher.hashChar(hashcode, b0);
-                continue;
-            }
-            int b1 = data[index++] & 0xff;
-            if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx
-                int ch = ((0x1f & b0)<<6) + (0x3f & b1); // yyy yyxx xxxx (0x80 to 0x7ff)
-                hashcode = StringHasher.hashChar(hashcode, ch);
-                continue;
-            }
-            int b2 = data[index++] & 0xff;
-            if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
-                int ch = ((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2); // zzzz yyyy yyxx xxxx (0x800 to 0xffff)
-                hashcode = StringHasher.hashChar(hashcode, ch);
-                continue;
-            }
-            int b3 = data[index++] & 0xff;  // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-            int ch = ((0x0f & b0)<<18) + ((0x3f & b1)<<12)
-                    + ((0x3f & b2)<<6) + (0x3f & b3);
-            if (ch < 0x10000)
-                hashcode = StringHasher.hashChar(hashcode, ch);
-            else {
-                hashcode = StringHasher.hashChar(hashcode, (int)(((ch-0x00010000)>>10)+0xd800));
-                hashcode = StringHasher.hashChar(hashcode, (int)(((ch-0x00010000)&0x3ff)+0xdc00));
-            }
-        }
-        return StringHasher.finishHash(hashcode);
-    }
-    //
-    //
-    //
-    private void init(StringPool stringPool, UTF8DataChunk prev) {
-        fStringPool = stringPool;
-        fRefCount = 1;
-        fChunk = prev == null ? 0 : prev.fChunk + 1;
-        fNextChunk = null;
-        fPreviousChunk = prev;
-        if (prev != null) {
-            prev.addRef();
-            prev.setNextChunk(this);
-            prev.removeRef();
-        }
-    }
-    //
-    // Constructor for factory method.
-    //
-    private UTF8DataChunk(StringPool stringPool, UTF8DataChunk prev) {
-        init(stringPool, prev);
-    }
-    //
-    //
-    //
-    private final UTF8DataChunk chunkFor(int offset) {
-        if ((offset >> CHUNK_SHIFT) == fChunk)
-            return this;
-        return slowChunkFor(offset);
-    }
-    private UTF8DataChunk slowChunkFor(int offset) {
-        int firstChunk = offset >> CHUNK_SHIFT;
-        UTF8DataChunk dataChunk = this;
-        while (firstChunk != dataChunk.fChunk)
-            dataChunk = dataChunk.fPreviousChunk;
-        return dataChunk;
-    }
-    //
-    //
-    //
-    private final void addRef() {
-        fRefCount++;
-//System.err.println(">>[" + fChunk + "] " + (fRefCount - 1) + " -> " + fRefCount);
-    }
-    //
-    //
-    //
-    private final void removeRef() {
-        fRefCount--;
-//System.err.println("<<[" + fChunk + "] " + (fRefCount + 1) + " -> " + fRefCount);
-        if (fRefCount == 0) {
-//System.err.println("[" + fChunk + "] recycled a " + fData.length + " character array");
-            fStringPool = null;
-            fChunk = -1;
-//            fData = null;
-            fPreviousChunk = null;
-            synchronized (UTF8DataChunk.class) {
-                /*** Only keep one free chunk at a time! ***
-                fNextChunk = fgFreeChunks;
-                /***/
-                fNextChunk = null;
-                fgFreeChunks = this;
-            }
-        }
-    }
-    //
-    //
-    //
-    private void setNextChunk(UTF8DataChunk nextChunk) {
-        if (nextChunk == null) {
-            if (fNextChunk != null)
-                fNextChunk.removeRef();
-        } else if (fNextChunk == null) {
-            nextChunk.addRef();
-        } else
-            throw new RuntimeException("UTF8DataChunk::setNextChunk");
-        fNextChunk = nextChunk;
-    }
-    //
-    //
-    //
-    private StringPool fStringPool;
-    private int fRefCount;
-    private int fChunk;
-    private byte[] fData = null;
-    private UTF8DataChunk fNextChunk;
-    private UTF8DataChunk fPreviousChunk;
-    private static UTF8DataChunk fgFreeChunks = null;
-    private static char[] fgTempBuffer = null;
-    private static Object fgTempBufferLock = new Object();
-}
diff --git a/src/org/apache/xerces/utils/XMLCharacterProperties.java b/src/org/apache/xerces/utils/XMLCharacterProperties.java
deleted file mode 100644
index 6a2c121..0000000
--- a/src/org/apache/xerces/utils/XMLCharacterProperties.java
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-/** 
- * A class representing properties of characters according to various
- * W3C recommendations
- *
- * XMLCharacterProperties provides convenience methods for commonly used
- * character tests.
- *
- * For performance reasons, the tables used by the convenience methods are
- * also public, and are directly accessed by performance critical routines.
- *
- */
-
-public final class XMLCharacterProperties {
-    /*
-     * [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
-     *
-     * Note: This is the same as the ascii portion of the
-     *       NameChar definition.
-     */
-    /** 
-     * Check to see if a string is a valid version string according to
-     * [26] in the XML 1.0 Recommendation
-     *
-     * @param version string to check
-     * @return true if version is a valid version string
-     */
-    public static boolean validVersionNum(String version) {
-        if (version.length() == 0)
-            return false;
-        for (int i = 0; i < version.length(); i++) {
-            char ch = version.charAt(i);
-            if (ch > 'z' || fgAsciiNameChar[ch] == 0)
-                return false;
-        }
-        return true;
-    }
-    /*
-     * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
-     */
-    /**
-     * Check to see if a string is a valid encoding name according to [81]
-     * in the XML 1.0 Recommendation
-     * 
-     * @param encoding string to check
-     * @return true if encoding is a valid encoding name
-     */
-    public static boolean validEncName(String encoding) {
-        if (encoding.length() == 0)
-            return false;
-        char ch = encoding.charAt(0);
-        if (ch > 'z' || fgAsciiAlphaChar[ch] == 0)
-            return false;
-        for (int i = 1; i < encoding.length(); i++) {
-            ch = encoding.charAt(i);
-            if (ch > 'z' || fgAsciiEncNameChar[ch] == 0)
-                return false;
-        }
-        return true;
-    }
-    /*
-     * [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
-     */
-    /** 
-     * Check to see if a string is a valid public identifier according to [13]
-     * in the XML 1.0 Recommendation
-     *
-     * @param publicId string to check
-     * @return true if publicId is a valid public identifier
-     */
-    public static int validPublicId(String publicId) {
-        if (publicId.length() == 0)
-            return -1;
-        for (int i = 0; i < publicId.length(); i++) {
-            char ch = publicId.charAt(i);
-            if (ch > 'z' || fgAsciiPubidChar[ch] == 0)
-                return i;
-        }
-        return -1;
-    }
-    /*
-     * [5] Name ::= (Letter | '_' | ':') (NameChar)*
-     */
-    /**
-     * Check to see if a string is a valid Name according to [5]
-     * in the XML 1.0 Recommendation
-     *
-     * @param name string to check
-     * @return true if name is a valid Name
-     */
-    public static boolean validName(String name) {
-        if (name.length() == 0)
-            return false;
-        char ch = name.charAt(0);
-        if (ch > 'z') {
-            if ((fgCharFlags[ch] & E_InitialNameCharFlag) == 0)
-                return false;
-        } else if (fgAsciiInitialNameChar[ch] == 0)
-            return false;
-        for (int i = 1; i < name.length(); i++) {
-            ch = name.charAt(i);
-            if (ch > 'z') {
-                if ((fgCharFlags[ch] & E_NameCharFlag) == 0)
-                    return false;
-            } else if (fgAsciiNameChar[ch] == 0)
-                return false;
-        }
-        return true;
-    }
-    
-    /*
-     * from the namespace rec
-     * [5] NCName ::= (Letter | '_' | ':') (NameNCChar)*
-     */
-    /**
-     * Check to see if a string is a valid NCName according to [5]
-     * from the XML Namespaces 1.0 Recommendation
-     *
-     * @param name string to check
-     * @return true if name is a valid NCName
-     */
-    public static boolean validNCName(String name) {
-        if (name.length() == 0)
-            return false;
-        char ch = name.charAt(0);
-        if (ch > 'z') {
-            if ((fgCharFlags[ch] & E_InitialNameCharFlag) == 0)
-                return false;
-        } else if (fgAsciiInitialNCNameChar[ch] == 0)
-            return false;
-        for (int i = 1; i < name.length(); i++) {
-            ch = name.charAt(i);
-            if (ch > 'z') {
-                if ((fgCharFlags[ch] & E_NameCharFlag) == 0)
-                    return false;
-            } else if (fgAsciiNCNameChar[ch] == 0)
-                return false;
-        }
-        return true;
-    }
-    
-    
-    /*
-     * [7] Nmtoken ::= (NameChar)+
-     */
-    /** 
-     * Check to see if a string is a valid Nmtoken according to [7]
-     * in the XML 1.0 Recommendation
-     *
-     * @param nmtoken string to checj
-     * @return true if nmtoken is a valid Nmtoken
-     */
-    public static boolean validNmtoken(String nmtoken) {
-        if (nmtoken.length() == 0)
-            return false;
-        for (int i = 0; i < nmtoken.length(); i++) {
-            char ch = nmtoken.charAt(i);
-            if (ch > 'z') {
-                if ((fgCharFlags[ch] & E_NameCharFlag) == 0)
-                    return false;
-            } else if (fgAsciiNameChar[ch] == 0) {
-                return false;
-            }
-        }
-        return true;
-    }
-    /*
-     * Here are tables used to build character properties.
-     */
-    public static final byte fgAsciiXDigitChar[] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // '0' - '9'
-        0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 'A' - 'F'
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 'a' - 'f'
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    };
-    public static final byte fgAsciiAlphaChar[] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'A' - 'O'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // 'P' - 'Z'
-        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'a' - 'o'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0  // 'p' - 'z'
-    };
-    public static final byte fgAsciiEncNameChar[] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, // '-' is 0x2D and '.' is 0x2E
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // '0' - '9'
-        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'A' - 'O'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 'P' - 'Z' and '_' is 0x5F
-        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'a' - 'o'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0  // 'p' - 'z'
-    };
-    public static final byte fgAsciiPubidChar[] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // ' ', '!', '#', '$', '%',
-                                                        // '\'', '(', ')', '*', '+', ',', '-', '.', '/'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, // '0' - '9', ':', ';', '=', '?'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // '@', 'A' - 'O'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 'P' - 'Z' and '_' is 0x5F
-        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'a' - 'o'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0  // 'p' - 'z'
-    };
-    public static final byte fgAsciiInitialNameChar[] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // ':' is 0x3A
-        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'A' - 'O'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 'P' - 'Z' and '_' is 0x5F
-        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'a' - 'o'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0  // 'p' - 'z'
-    };
-    public static final byte fgAsciiNameChar[] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, // '-' is 0x2D and '.' is 0x2E
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // '0' - '9' and ':' is 0x3A
-        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'A' - 'O'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 'P' - 'Z' and '_' is 0x5F
-        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'a' - 'o'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0  // 'p' - 'z'
-    };
-    public static final byte fgAsciiInitialNCNameChar[] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ':' is 0x3A
-        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'A' - 'O'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 'P' - 'Z' and '_' is 0x5F
-        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'a' - 'o'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0  // 'p' - 'z'
-    };
-    public static final byte fgAsciiNCNameChar[] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, // '-' is 0x2D and '.' is 0x2E
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // '0' - '9' and ':' is 0x3A
-        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'A' - 'O'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 'P' - 'Z' and '_' is 0x5F
-        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'a' - 'o'
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0  // 'p' - 'z'
-    };
-    public static final byte fgAsciiCharData[] = {
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, // tab is 0x09
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-        0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, // '&' is 0x26
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, // '<' is 0x3C
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, // ']' is 0x5D
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    };
-    public static final byte fgAsciiWSCharData[] = {
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 4, 4, 5, 4, 4, // tab is 0x09,  LF is 0x0A,  CR is 0x0D
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-        5, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ' ' is 0x20, '&' is 0x26
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, // '<' is 0x3C
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, // ']' is 0x5D
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    };
-    public static final byte E_CharDataFlag = 1<<0;
-    public static final byte E_InitialNameCharFlag = 1<<1;
-    public static final byte E_NameCharFlag = 1<<2;
-    public static byte[] fgCharFlags = null;
-    public static synchronized void initCharFlags() {
-        if (fgCharFlags == null) {
-            fgCharFlags = new byte[0x10000];
-            setFlagForRange(fgCharDataRanges, E_CharDataFlag);
-            setFlagForRange(fgInitialNameCharRanges, (byte)(E_InitialNameCharFlag | E_NameCharFlag));
-            setFlagForRange(fgNameCharRanges, E_NameCharFlag);
-        }
-    }
-    private static void setFlagForRange(char[] ranges, byte flag)
-    {
-        int i;
-        int ch;
-        for (i = 0; (ch = ranges[i]) != 0; i += 2) {
-            int endch = ranges[i+1];
-            while (ch <= endch)
-                fgCharFlags[ch++] |= flag;
-        }
-        for (i++; (ch = ranges[i]) != 0; i++)
-            fgCharFlags[ch] |= flag;
-    }
-    /*
-     *  [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF]        // any Unicode character, excluding the
-     *               | [#xE000-#xFFFD] | [#x10000-#x10FFFF] // surrogate blocks, FFFE, and FFFF.
-     * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
-     *
-     * We will use Char - ( [^<&] | ']' | #xA | #xD ) and handle the special cases inline.
-     */
-    private static final char fgCharDataRanges[] = {
-        0x0020, 0x0025, // '&' is 0x0026
-        0x0027, 0x003B, // '<' is 0x003C
-        0x003D, 0x005C, // ']' is 0x005D
-        0x005E, 0xD7FF,
-        0xE000, 0xFFFD,
-            0x0000,
-        0x0009,         // tab
-            0x0000
-    };
-    /*
-     *  [5] Name ::= (Letter | '_' | ':') (NameChar)*
-     *  [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender
-     * [84] Letter ::= BaseChar | Ideographic
-     * [85] BaseChar ::= <see standard>
-     * [86] Ideographic ::= <see standard>
-     * [87] CombiningChar ::= <see standard>
-     * [88] Digit ::= <see standard>
-     * [89] Extender ::= <see standard>
-     */
-    private static final char fgInitialNameCharRanges[] = {
-        //
-        // Ranges:
-        //
-        //  BaseChar ranges
-        //
-        0x0041, 0x005A, 0x0061, 0x007A, 0x00C0, 0x00D6, 0x00D8, 0x00F6,
-        0x00F8, 0x0131, 0x0134, 0x013E, 0x0141, 0x0148, 0x014A, 0x017E,
-        0x0180, 0x01C3, 0x01CD, 0x01F0, 0x01F4, 0x01F5, 0x01FA, 0x0217,
-        0x0250, 0x02A8, 0x02BB, 0x02C1, 0x0388, 0x038A, 0x038E, 0x03A1,
-        0x03A3, 0x03CE, 0x03D0, 0x03D6, 0x03E2, 0x03F3, 0x0401, 0x040C,
-        0x040E, 0x044F, 0x0451, 0x045C, 0x045E, 0x0481, 0x0490, 0x04C4,
-        0x04C7, 0x04C8, 0x04CB, 0x04CC, 0x04D0, 0x04EB, 0x04EE, 0x04F5,
-        0x04F8, 0x04F9, 0x0531, 0x0556, 0x0561, 0x0586, 0x05D0, 0x05EA,
-        0x05F0, 0x05F2, 0x0621, 0x063A, 0x0641, 0x064A, 0x0671, 0x06B7,
-        0x06BA, 0x06BE, 0x06C0, 0x06CE, 0x06D0, 0x06D3, 0x06E5, 0x06E6,
-        0x0905, 0x0939, 0x0958, 0x0961, 0x0985, 0x098C, 0x098F, 0x0990,
-        0x0993, 0x09A8, 0x09AA, 0x09B0, 0x09B6, 0x09B9, 0x09DC, 0x09DD,
-        0x09DF, 0x09E1, 0x09F0, 0x09F1, 0x0A05, 0x0A0A, 0x0A0F, 0x0A10,
-        0x0A13, 0x0A28, 0x0A2A, 0x0A30, 0x0A32, 0x0A33, 0x0A35, 0x0A36,
-        0x0A38, 0x0A39, 0x0A59, 0x0A5C, 0x0A72, 0x0A74, 0x0A85, 0x0A8B,
-        0x0A8F, 0x0A91, 0x0A93, 0x0AA8, 0x0AAA, 0x0AB0, 0x0AB2, 0x0AB3,
-        0x0AB5, 0x0AB9, 0x0B05, 0x0B0C, 0x0B0F, 0x0B10, 0x0B13, 0x0B28,
-        0x0B2A, 0x0B30, 0x0B32, 0x0B33, 0x0B36, 0x0B39, 0x0B5C, 0x0B5D,
-        0x0B5F, 0x0B61, 0x0B85, 0x0B8A, 0x0B8E, 0x0B90, 0x0B92, 0x0B95,
-        0x0B99, 0x0B9A, 0x0B9E, 0x0B9F, 0x0BA3, 0x0BA4, 0x0BA8, 0x0BAA,
-        0x0BAE, 0x0BB5, 0x0BB7, 0x0BB9, 0x0C05, 0x0C0C, 0x0C0E, 0x0C10,
-        0x0C12, 0x0C28, 0x0C2A, 0x0C33, 0x0C35, 0x0C39, 0x0C60, 0x0C61,
-        0x0C85, 0x0C8C, 0x0C8E, 0x0C90, 0x0C92, 0x0CA8, 0x0CAA, 0x0CB3,
-        0x0CB5, 0x0CB9, 0x0CE0, 0x0CE1, 0x0D05, 0x0D0C, 0x0D0E, 0x0D10,
-        0x0D12, 0x0D28, 0x0D2A, 0x0D39, 0x0D60, 0x0D61, 0x0E01, 0x0E2E,
-        0x0E32, 0x0E33, 0x0E40, 0x0E45, 0x0E81, 0x0E82, 0x0E87, 0x0E88,
-        0x0E94, 0x0E97, 0x0E99, 0x0E9F, 0x0EA1, 0x0EA3, 0x0EAA, 0x0EAB,
-        0x0EAD, 0x0EAE, 0x0EB2, 0x0EB3, 0x0EC0, 0x0EC4, 0x0F40, 0x0F47,
-        0x0F49, 0x0F69, 0x10A0, 0x10C5, 0x10D0, 0x10F6, 0x1102, 0x1103,
-        0x1105, 0x1107, 0x110B, 0x110C, 0x110E, 0x1112, 0x1154, 0x1155,
-        0x115F, 0x1161, 0x116D, 0x116E, 0x1172, 0x1173, 0x11AE, 0x11AF,
-        0x11B7, 0x11B8, 0x11BC, 0x11C2, 0x1E00, 0x1E9B, 0x1EA0, 0x1EF9,
-        0x1F00, 0x1F15, 0x1F18, 0x1F1D, 0x1F20, 0x1F45, 0x1F48, 0x1F4D,
-        0x1F50, 0x1F57, 0x1F5F, 0x1F7D, 0x1F80, 0x1FB4, 0x1FB6, 0x1FBC,
-        0x1FC2, 0x1FC4, 0x1FC6, 0x1FCC, 0x1FD0, 0x1FD3, 0x1FD6, 0x1FDB,
-        0x1FE0, 0x1FEC, 0x1FF2, 0x1FF4, 0x1FF6, 0x1FFC, 0x212A, 0x212B,
-        0x2180, 0x2182, 0x3041, 0x3094, 0x30A1, 0x30FA, 0x3105, 0x312C,
-        0xAC00, 0xD7A3,
-        //
-        //  Ideographic ranges
-        //
-        0x3021, 0x3029, 0x4E00, 0x9FA5,
-        //
-        // Ranges end marker
-        //
-        0x0000,
-        //
-        // Single char values
-        //
-        0x003A, // ':'
-        0x005F, // '_'
-        //
-        //  BaseChar singles
-        //
-        0x0386, 0x038C, 0x03DA, 0x03DC, 0x03DE, 0x03E0, 0x0559, 0x06D5,
-        0x093D, 0x09B2, 0x0A5E, 0x0A8D, 0x0ABD, 0x0AE0, 0x0B3D, 0x0B9C,
-        0x0CDE, 0x0E30, 0x0E84, 0x0E8A, 0x0E8D, 0x0EA5, 0x0EA7, 0x0EB0,
-        0x0EBD, 0x1100, 0x1109, 0x113C, 0x113E, 0x1140, 0x114C, 0x114E,
-        0x1150, 0x1159, 0x1163, 0x1165, 0x1167, 0x1169, 0x1175, 0x119E,
-        0x11A8, 0x11AB, 0x11BA, 0x11EB, 0x11F0, 0x11F9, 0x1F59, 0x1F5B,
-        0x1F5D, 0x1FBE, 0x2126, 0x212E,
-        //
-        //  Ideographic singles
-        //
-        0x3007,
-        //
-        // Singles end marker
-        //
-        0x0000
-    };
-    private static final char fgNameCharRanges[] = {
-        //
-        // Ranges:
-        //
-        0x002D, 0x002E, // '-' and '.'
-        //
-        //  CombiningChar ranges
-        //
-        0x0300, 0x0345, 0x0360, 0x0361, 0x0483, 0x0486, 0x0591, 0x05A1,
-        0x05A3, 0x05B9, 0x05BB, 0x05BD, 0x05C1, 0x05C2, 0x064B, 0x0652,
-        0x06D6, 0x06DC, 0x06DD, 0x06DF, 0x06E0, 0x06E4, 0x06E7, 0x06E8,
-        0x06EA, 0x06ED, 0x0901, 0x0903, 0x093E, 0x094C, 0x0951, 0x0954,
-        0x0962, 0x0963, 0x0981, 0x0983, 0x09C0, 0x09C4, 0x09C7, 0x09C8,
-        0x09CB, 0x09CD, 0x09E2, 0x09E3, 0x0A40, 0x0A42, 0x0A47, 0x0A48,
-        0x0A4B, 0x0A4D, 0x0A70, 0x0A71, 0x0A81, 0x0A83, 0x0ABE, 0x0AC5,
-        0x0AC7, 0x0AC9, 0x0ACB, 0x0ACD, 0x0B01, 0x0B03, 0x0B3E, 0x0B43,
-        0x0B47, 0x0B48, 0x0B4B, 0x0B4D, 0x0B56, 0x0B57, 0x0B82, 0x0B83,
-        0x0BBE, 0x0BC2, 0x0BC6, 0x0BC8, 0x0BCA, 0x0BCD, 0x0C01, 0x0C03,
-        0x0C3E, 0x0C44, 0x0C46, 0x0C48, 0x0C4A, 0x0C4D, 0x0C55, 0x0C56,
-        0x0C82, 0x0C83, 0x0CBE, 0x0CC4, 0x0CC6, 0x0CC8, 0x0CCA, 0x0CCD,
-        0x0CD5, 0x0CD6, 0x0D02, 0x0D03, 0x0D3E, 0x0D43, 0x0D46, 0x0D48,
-        0x0D4A, 0x0D4D, 0x0E34, 0x0E3A, 0x0E47, 0x0E4E, 0x0EB4, 0x0EB9,
-        0x0EBB, 0x0EBC, 0x0EC8, 0x0ECD, 0x0F18, 0x0F19, 0x0F71, 0x0F84,
-        0x0F86, 0x0F8B, 0x0F90, 0x0F95, 0x0F99, 0x0FAD, 0x0FB1, 0x0FB7,
-        0x20D0, 0x20DC, 0x302A, 0x302F,
-        //
-        //  Digit ranges
-        //
-        0x0030, 0x0039, 0x0660, 0x0669, 0x06F0, 0x06F9, 0x0966, 0x096F,
-        0x09E6, 0x09EF, 0x0A66, 0x0A6F, 0x0AE6, 0x0AEF, 0x0B66, 0x0B6F,
-        0x0BE7, 0x0BEF, 0x0C66, 0x0C6F, 0x0CE6, 0x0CEF, 0x0D66, 0x0D6F,
-        0x0E50, 0x0E59, 0x0ED0, 0x0ED9, 0x0F20, 0x0F29,
-        //
-        //  Extender ranges
-        //
-        0x3031, 0x3035, 0x309D, 0x309E, 0x30FC, 0x30FE,
-        //
-        // Ranges end marker
-        //
-        0x0000,
-        //
-        // Single char values
-        //
-        //  CombiningChar singles
-        //
-        0x05BF, 0x05C4, 0x0670, 0x093C, 0x094D, 0x09BC, 0x09BE, 0x09BF,
-        0x09D7, 0x0A02, 0x0A3C, 0x0A3E, 0x0A3F, 0x0ABC, 0x0B3C, 0x0BD7,
-        0x0D57, 0x0E31, 0x0EB1, 0x0F35, 0x0F37, 0x0F39, 0x0F3E, 0x0F3F,
-        0x0F97, 0x0FB9, 0x20E1, 0x3099, 0x309A,
-        //
-        //  Extender singles
-        //
-        0x00B7, 0x02D0, 0x02D1, 0x0387, 0x0640, 0x0E46, 0x0EC6, 0x3005,
-        //
-        // Singles end marker
-        //
-        0x0000
-    };
-}
diff --git a/src/org/apache/xerces/utils/XMLMessageProvider.java b/src/org/apache/xerces/utils/XMLMessageProvider.java
deleted file mode 100644
index f23b385..0000000
--- a/src/org/apache/xerces/utils/XMLMessageProvider.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-import java.util.Locale;
-
-/**
- * Interface describing how to provide localized error messages to the XMLErrorReporter
- *
- * @see org.apache.xerces.framework.XMLErrorReporter
- */
-public interface XMLMessageProvider {
-    /**
-     * Set the locale to be used for error messages
-     *
-     * @param locale the new locale
-     */
-    public void setLocale(Locale locale);
-    /**
-     * Get the locale being used for error messages
-     *
-     * @return the locale
-     */
-    public Locale getLocale();
-    /**
-     * Creates a message from the specified key and replacement
-     * arguments, localized to the given locale.
-     *
-     * @param locale    The requested locale of the message to be
-     *                  created.
-     * @param key       The key for the message text.
-     * @param args      The arguments to be used as replacement text
-     *                  in the message created.
-     */
-    public String createMessage(Locale locale, int majorCode, int minorCode, Object args[]);
-};
diff --git a/src/org/apache/xerces/utils/XMLMessages.java b/src/org/apache/xerces/utils/XMLMessages.java
deleted file mode 100644
index 308f41c..0000000
--- a/src/org/apache/xerces/utils/XMLMessages.java
+++ /dev/null
@@ -1,1266 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils;
-
-import java.util.Locale;
-import java.util.ResourceBundle;
-import java.util.ListResourceBundle;
-
-/**
- * XMLMessages provides error messages for the XML 1.0 Recommendation and for 
- * the Namespaces Recommendation
- *
- */
-public class XMLMessages implements XMLMessageProvider {
-    /**
-     * The domain of messages concerning the XML 1.0 specification.
-     */
-    public static final String XML_DOMAIN = "http://www.w3.org/TR/1998/REC-xml-19980210";
-    public static final String XMLNS_DOMAIN = "http://www.w3.org/TR/1999/REC-xml-names-19990114";
-
-    /**
-     *
-     */
-    public void setLocale(Locale locale) {
-        fLocale = locale;
-    }
-    /**
-     *
-     */
-    public Locale getLocale() {
-        return fLocale;
-    }
-
-    /**
-     * Creates a message from the specified key and replacement
-     * arguments, localized to the given locale.
-     *
-     * @param locale    The requested locale of the message to be
-     *                  created.
-     * @param key       The key for the message text.
-     * @param args      The arguments to be used as replacement text
-     *                  in the message created.
-     */
-    public String createMessage(Locale locale, int majorCode, int minorCode, Object args[]) {
-        boolean throwex = false;
-        if (fResourceBundle == null || locale != fLocale) {
-            if (locale != null)
-                fResourceBundle = ListResourceBundle.getBundle("org.apache.xerces.msg.XMLMessages", locale);
-            if (fResourceBundle == null)
-                fResourceBundle = ListResourceBundle.getBundle("org.apache.xerces.msg.XMLMessages");
-        }
-        if (majorCode < 0 || majorCode >= fgMessageKeys.length - 1) {
-            majorCode = MSG_BAD_MAJORCODE;
-            throwex = true;
-        }
-        String msgKey = fgMessageKeys[majorCode];
-        String msg = fResourceBundle.getString(msgKey);
-        if (args != null) {
-            try {
-                msg = java.text.MessageFormat.format(msg, args);
-            } catch (Exception e) {
-                msg = fResourceBundle.getString(fgMessageKeys[MSG_FORMAT_FAILURE]);
-                msg += " " + fResourceBundle.getString(msgKey);
-            }
-        }
-/*
-        if (minorCode > 0 && minorCode < fgConstraints.length - 1) {
-            Constraint c = fgConstraints[minorCode];
-            String prefix = "{ " + c.sections;
-            if (c.productions != null && c.productions.length() != 0)
-                prefix = prefix + " " + c.productions;
-            msg = prefix + " } " + msg;
-        }
- */
-        if (throwex) {
-            throw new RuntimeException(msg);
-        }
-        return msg;
-    }
-    //
-    //
-    //
-    private Locale fLocale = null;
-    private ResourceBundle fResourceBundle = null;
-    //
-    //
-    //
-    public static final int
-        MSG_BAD_MAJORCODE = 0,              //  majorCode parameter to createMessage was out of bounds
-        MSG_FORMAT_FAILURE = 1,             //  exception thrown during messageFormat call
-        MSG_LESSTHAN_IN_ATTVALUE = 2,       //  '<' found in attribute value
-        MSG_ROOT_ELEMENT_TYPE = 3,          //  document root element type does not match the doctypedecl Name
-        MSG_IDREFS_INVALID = 4,             //  attributes of type IDREFS must match the Names production
-        MSG_NMTOKENS_INVALID = 5,           //  attributes of type NMTOKENS must match the Nmtokens production
-        MSG_RESERVED_PITARGET = 6,          //  PITarget matching [Xx][Mm][Ll] is reserved
-        MSG_SPACE_REQUIRED_IN_PI = 7,       //  white space is required between PITarget and data
-        MSG_INVALID_CHAR_IN_PI = 8,         //  invalid character found in PI data
-        MSG_DASH_DASH_IN_COMMENT = 9,       //  the string "--" in not allowed in comments
-        MSG_INVALID_CHAR_IN_COMMENT = 10,   //  invalid character found in comment
-        MSG_INVALID_CHARREF = 11,           //  invalid value for character reference
-        MSG_INVALID_CHAR_IN_ATTVALUE = 12,  //  invalid character found in attribute value
-        MSG_QUOTE_REQUIRED_IN_ATTVALUE = 13, //  attribute value was not a quoted string
-        MSG_NAME_REQUIRED_IN_REFERENCE = 14, //  a Name did not follow the '&' in the entity reference
-        MSG_SEMICOLON_REQUIRED_IN_REFERENCE = 15, //  a ';' did not follow the Name in the entity reference
-        MSG_DIGIT_REQUIRED_IN_CHARREF = 16,  //  a decimal representation did not follow the "&#" in the character reference
-        MSG_HEXDIGIT_REQUIRED_IN_CHARREF = 17, //  a hexadecimal representation did not follow the "&#x" in the character reference
-        MSG_SEMICOLON_REQUIRED_IN_CHARREF = 18, //  the ';' delimiter was not found in the character reference
-        MSG_QUOTE_REQUIRED_IN_SYSTEMID = 19, //  system identifier was not a quoted string
-        MSG_INVALID_CHAR_IN_SYSTEMID = 20,  //  invalid character found in system identifier
-        MSG_QUOTE_REQUIRED_IN_PUBLICID = 21, //  public identifier was not a quoted string
-        MSG_INVALID_CHAR_IN_PUBLICID = 22,  //  invalid character found in public identifier
-        MSG_INCLUDESECT_UNTERMINATED = 23,  //  includeSect must end with "]]>"
-        MSG_IGNORESECT_UNTERMINATED = 24,   //  ignoreSect must end with "]]>"
-        MSG_INVALID_CHAR_IN_IGNORESECT = 25, //  invalid character found in ignoreSect
-        MSG_ELEMENT_UNTERMINATED = 26,      //  element type not followed by attributes, ">" or "/>"
-        MSG_EQ_REQUIRED_IN_ATTRIBUTE = 27,   //  attribute name not followed by "="
-        MSG_ATTRIBUTE_NOT_UNIQUE = 28,      //  specified attributes must be unique within the element tag
-        MSG_ENCODINGDECL_REQUIRED = 29,      //  the "encoding" declaration is required in a text declaration
-        MSG_VERSIONINFO_REQUIRED = 30,       //  the "version" is required in the XML declaration
-        MSG_EQ_REQUIRED_IN_XMLDECL = 31,     //  the '=' character must follow \"{0}\" in the XML declaration
-        MSG_EQ_REQUIRED_IN_TEXTDECL = 32,    //  the '=' character must follow \"{0}\" in the text declaration
-        MSG_QUOTE_REQUIRED_IN_XMLDECL = 33,  //  quote missing in the XML declaration
-        MSG_QUOTE_REQUIRED_IN_TEXTDECL = 34, //  quote missing in the text declaration
-        MSG_INVALID_CHAR_IN_XMLDECL = 35,   //  invalid character found in the XML declaration
-        MSG_INVALID_CHAR_IN_TEXTDECL = 36,  //  invalid character found in the text declaration
-        MSG_VERSIONINFO_INVALID = 37,       //  Invalid XML version format, \"{0}\"
-        MSG_VERSION_NOT_SUPPORTED = 38,     //  unsupported XML version
-        MSG_SPACE_REQUIRED_IN_TEXTDECL = 39, //  white space required between version and encoding
-        MSG_ENCODINGDECL_INVALID = 40,      //  invalid encoding name
-        MSG_SDDECL_INVALID = 41,            //  invalid \"standalone\" attribute value. Must be "yes" or "no"
-        MSG_XMLDECL_UNTERMINATED = 42,      //  "\"?>\" expected.
-        MSG_TEXTDECL_UNTERMINATED = 43,     //  "\"?>\" expected.
-        MSG_INVALID_CHAR_IN_INTERNAL_SUBSET = 44, //  invalid character found in the internal subset of the dtd
-        MSG_INVALID_CHAR_IN_EXTERNAL_SUBSET = 45, //  invalid character found in the external subset of the dtd
-        MSG_INVALID_CHAR_IN_ENTITYVALUE = 46, //  invalid character found in entity value
-        MSG_MIXED_CONTENT_UNTERMINATED = 47, //  mixed content model with element types must end with ")*"
-        MSG_NAME_REQUIRED_IN_PEREFERENCE = 48, //  a Name did not follow the '&' in the parameter entity reference
-        MSG_SEMICOLON_REQUIRED_IN_PEREFERENCE = 49, //  a ';' did not follow the Name in the parameter entity reference
-        MSG_EXTERNALID_REQUIRED = 50,        //  an external id did not begin with SYSTEM or PUBLIC
-        MSG_PEREFERENCE_WITHIN_MARKUP = 51, //  a PEReference is not allowed within markup in the internal subset of the DTD
-        MSG_INVALID_CHAR_IN_PROLOG = 52,    //  invalid character found in prolog
-        MSG_INVALID_CHAR_IN_MISC = 53,      //  invalid character found in trailing misc
-        MSG_INVALID_CHAR_IN_CDSECT = 54,    //  invalid character found in cdata section
-        MSG_INVALID_CHAR_IN_CONTENT = 55,   //  invalid character found in content
-        MSG_ETAG_REQUIRED = 56,              //  end of input before end of element content
-        MSG_ETAG_UNTERMINATED = 57,         //  the end-tag did not end with a '>'
-        MSG_ATTRIBUTE_NAME_REQUIRED_IN_ATTDEF = 58, //  attribute name expected
-        MSG_ATTTYPE_REQUIRED_IN_ATTDEF = 59, //  attribute type expected
-        MSG_PUBIDCHAR_ILLEGAL = 60,        //  illegal character found in public identifier
-        MSG_ENCODING_NOT_SUPPORTED = 61,   //  encoding is not supported
-        MSG_ENTITY_NOT_DECLARED = 62,      //  entity was not declared
-        MSG_REFERENCE_TO_UNPARSED_ENTITY = 63,
-        MSG_REFERENCE_TO_EXTERNAL_ENTITY = 64,
-        MSG_XML_LANG_INVALID = 65,         //  xml:lang attribute value does not match LanguageID production
-        MSG_CDSECT_UNTERMINATED = 66,      //  CDATA sections must end with "]]>"
-        MSG_DUPLICATE_TYPE_IN_MIXED_CONTENT = 67,
-        MSG_ELEMENT_ENTITY_MISMATCH = 68,
-        MSG_ID_DEFAULT_TYPE_INVALID = 69,
-        MSG_ENCODING_REQUIRED = 70,
-        MSG_RECURSIVE_REFERENCE = 71,
-        MSG_RECURSIVE_PEREFERENCE = 72,
-        MSG_IMPROPER_DECLARATION_NESTING = 73, // "Parameter entity replacement text must include declarations or proper pairs of ''<'' and ''>''. (entity: \"%{0};\")"
-        MSG_IMPROPER_GROUP_NESTING = 74,    // "Parameter entity replacement text must include proper pairs of parentheses in content model, \"%{0};\"."
-        MSG_ID_INVALID = 75,
-        MSG_ID_NOT_UNIQUE = 76,
-        MSG_IDREF_INVALID = 77,
-        MSG_NMTOKEN_INVALID = 78,
-        MSG_ENTITY_INVALID = 79,
-        MSG_ENTITIES_INVALID = 80,
-        MSG_ELEMENT_WITH_ID_REQUIRED = 81,
-        MSG_ATTRIBUTE_NOT_DECLARED = 82,
-        MSG_ELEMENT_NOT_DECLARED = 83,
-        MSG_AVAILABLE1 = 84,
-        MSG_DUPLICATE_ATTDEF = 85,
-        MSG_MORE_THAN_ONE_ID_ATTRIBUTE = 86,
-        MSG_CONTENT_INVALID = 87,
-        MSG_CONTENT_INCOMPLETE = 88,
-        MSG_ELEMENT_ALREADY_DECLARED = 89,
-        MSG_ATTRIBUTE_VALUE_NOT_IN_LIST = 90,
-        MSG_AVAILABLE2 = 91,
-        MSG_UNDECLARED_ELEMENT_IN_CONTENTSPEC = 92,
-        MSG_FIXED_ATTVALUE_INVALID = 93,
-        MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED = 94,
-        MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED = 95,
-        MSG_AVAILABLE3 = 96,
-        MSG_AVAILABLE4 = 97,
-        MSG_CLOSE_PAREN_REQUIRED_IN_CHILDREN = 98,
-        MSG_AVAILABLE5 = 99,
-        MSG_SYSTEMID_UNTERMINATED = 100,
-        MSG_PUBLICID_UNTERMINATED = 101,
-        MSG_EXTERNAL_ENTITY_NOT_PERMITTED = 102,
-        MSG_AVAILABLE6 = 103,
-        MSG_XMLDECL_MUST_BE_FIRST = 104,
-        MSG_TEXTDECL_MUST_BE_FIRST = 105,
-        MSG_ELEMENTDECL_UNTERMINATED = 106,
-        MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_PEDECL = 107,
-        MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_ENTITYDECL = 108,
-        MSG_SPACE_REQUIRED_BEFORE_PERCENT_IN_PEDECL = 109,
-        MSG_ENTITY_NAME_REQUIRED_IN_ENTITYDECL = 110,
-        MSG_SPACE_REQUIRED_AFTER_ENTITY_NAME_IN_ENTITYDECL = 111,
-        MSG_ENTITYDECL_UNTERMINATED = 112,
-        MSG_NOTATION_NAME_REQUIRED_FOR_UNPARSED_ENTITYDECL = 113,
-        MSG_NOTATION_NOT_DECLARED_FOR_UNPARSED_ENTITYDECL = 114,
-        MSG_NAME_REQUIRED_IN_NOTATIONTYPE = 115,
-        MSG_NMTOKEN_REQUIRED_IN_ENUMERATION = 116,
-        MSG_NOTATION_NOT_DECLARED_FOR_NOTATIONTYPE_ATTRIBUTE = 117,
-        MSG_NOTATIONTYPE_UNTERMINATED = 118,
-        MSG_ENUMERATION_UNTERMINATED = 119,
-        MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL = 120,
-        MSG_MORE_THAN_ONE_NOTATION_ATTRIBUTE = 121,
-        MSG_NOTATIONDECL_UNTERMINATED = 122,
-        MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE = 123,
-        MSG_CDEND_IN_CONTENT = 124,
-        MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL = 125,
-        MSG_TWO_COLONS_IN_QNAME = 126,
-        MSG_MARKUP_NOT_RECOGNIZED_IN_CONTENT = 127,
-        MSG_MARKUP_NOT_RECOGNIZED_IN_MISC = 128,
-        MSG_MARKUP_NOT_RECOGNIZED_IN_PROLOG = 129,
-        MSG_OPEN_PAREN_REQUIRED_IN_NOTATIONTYPE = 130,
-        MSG_PITARGET_REQUIRED = 131,
-        MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE = 132,
-        MSG_URI_FRAGMENT_IN_SYSTEMID = 133,
-        MSG_ROOT_ELEMENT_REQUIRED = 134,
-        MSG_SPACE_REQUIRED_AFTER_FIXED_IN_DEFAULTDECL = 135,
-        MSG_SPACE_REQUIRED_AFTER_NOTATION_IN_NOTATIONTYPE = 136,
-        MSG_SPACE_REQUIRED_AFTER_NOTATION_NAME_IN_NOTATIONDECL = 137,
-        MSG_SPACE_REQUIRED_BEFORE_ATTRIBUTE_NAME_IN_ATTDEF = 138,
-        MSG_SPACE_REQUIRED_BEFORE_ATTTYPE_IN_ATTDEF = 139,
-        MSG_SPACE_REQUIRED_BEFORE_DEFAULTDECL_IN_ATTDEF = 140,
-        MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ATTLISTDECL = 141,
-        MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_NOTATIONDECL = 142,
-        MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE = 143,
-        MSG_XML_SPACE_DECLARATION_ILLEGAL = 144,
-        MSG_CLOSE_PAREN_REQUIRED_IN_MIXED = 145,
-        MSG_CONTENTSPEC_REQUIRED_IN_ELEMENTDECL = 146,
-        MSG_DOCTYPEDECL_UNTERMINATED = 147,
-        MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL = 148,
-        MSG_ELEMENT_TYPE_REQUIRED_IN_MIXED_CONTENT = 149,
-        MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = 150,
-        MSG_ATTRIBUTE_VALUE_UNTERMINATED = 151,
-        MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN = 152,
-        MSG_ROOT_ELEMENT_TYPE_REQUIRED = 153,
-        MSG_SPACE_REQUIRED_AFTER_PUBIDLITERAL_IN_EXTERNALID = 154,
-        MSG_SPACE_REQUIRED_BEFORE_CONTENTSPEC_IN_ELEMENTDECL = 155,
-        MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ELEMENTDECL = 156,
-        MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_UNPARSED_ENTITYDECL = 157,
-        MSG_SPACE_REQUIRED_BEFORE_PUBIDLITERAL_IN_EXTERNALID = 158,
-        MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL = 159,
-        MSG_SPACE_REQUIRED_BEFORE_SYSTEMLITERAL_IN_EXTERNALID = 160,
-        MSG_REFERENCE_NOT_IN_ONE_ENTITY = 161,
-        MSG_COMMENT_NOT_IN_ONE_ENTITY = 162,
-        MSG_COMMENT_UNTERMINATED = 163,
-        MSG_PI_UNTERMINATED = 164,
-        MSG_PI_NOT_IN_ONE_ENTITY = 165,
-        MSG_REFERENCE_UNTERMINATED = 166,
-        MSG_PREFIX_DECLARED = 167,
-        MSG_ATT_DEFAULT_INVALID = 168,
-        MSG_GENERIC_SCHEMA_ERROR = 169,
-
-        // ...
-        MSG_MAX_CODE = 200;
-
-    private static final String[] fgMessageKeys = {
-        "BadMajorCode",                 //   0, "The majorCode parameter to createMessage was out of bounds."
-        "FormatFailed",                 //   1, "An internal error occurred while formatting the following message:"
-        "LessthanInAttValue",           //   2, "The attribute value must not contain the '<' character."
-        "RootElementTypeMustMatchDoctypedecl", //   3, "The document root element type \"{1}\" must match the document type declaration name \"{0}\"."
-        "IDREFSInvalid",                //   4, "Attribute value \"{1}\" of type IDREFS must be one or more names."
-        "NMTOKENSInvalid",              //   5, "Attribute value \"{1}\" of type NMTOKENS must contain one or more name tokens."
-        "ReservedPITarget",             //   6, "The processing instruction target matching \"[xX][mM][lL]\" is not allowed."
-        "SpaceRequiredInPI",            //   7, "White space is required between the processing instruction target and data."
-        "InvalidCharInPI",              //   8, "An invalid XML character (Unicode: 0x{0}) was found in the processing instruction."
-        "DashDashInComment",            //   9, "The string \"--\" is not permitted within comments."
-        "InvalidCharInComment",         //  10, "An invalid XML character (Unicode: 0x{0}) was found in the comment."
-        "InvalidCharRef",               //  11, "Character reference \"&#{0}\" is an invalid XML character."
-        "InvalidCharInAttValue",        //  12, "An invalid XML character (Unicode: 0x{0}) was found in the attribute value."
-        "QuoteRequiredInAttValue",      //  13, "The attribute value must begin with either a single or double quote character."
-        "NameRequiredInReference",      //  14, "The entity name must immediately follow the '&' in the entity reference."
-        "SemicolonRequiredInReference", //  15, "The entity reference must end with the ';' delimiter."
-        "DigitRequiredInCharRef",       //  16, "A decimal representation must immediately follow the \"&#\" in the character reference."
-        "HexdigitRequiredInCharRef",    //  17, "A hexadecimal representation must immediately follow the \"&#x\" in the character reference."
-        "SemicolonRequiredInCharRef",   //  18, "The character reference must end with the ';' delimiter."
-        "QuoteRequiredInSystemID",      //  19, "The system identifier must begin with either a single or double quote character."
-        "InvalidCharInSystemID",        //  20, "An invalid XML character (Unicode: 0x{0}) was found in the system identifier."
-        "QuoteRequiredInPublicID",      //  21, "The public identifier must begin with either a single or double quote character."
-        "InvalidCharInPublicID",        //  22, "An invalid XML character (Unicode: 0x{0}) was found in the public identifier."
-        "IncludeSectUnterminated",      //  23, "The included conditional section must end with \"]]>\"."
-        "IgnoreSectUnterminated",       //  24, "The excluded conditional section must end with \"]]>\"."
-        "InvalidCharInIgnoreSect",      //  25, "An invalid XML character (Unicode: 0x{0}) was found in the excluded conditional section."
-        "ElementUnterminated",          //  26, "Element type \"{0}\" must be followed by either attribute specifications, \">\" or \"/>\"."
-        "EqRequiredInAttribute",        //  27, "Attribute name \"{1}\" must be followed by the '=' character."
-        "AttributeNotUnique",           //  28, "Attribute \"{1}\" was already specified for element \"{0}\"."
-        "EncodingDeclRequired",         //  29, "The encoding declaration is required within a text declaration."
-        "VersionInfoRequired",          //  30, "The version is required within an XML declaration."
-        "EqRequiredInXMLDecl",          //  31, "The '=' character must follow \"{0}\" in the XML declaration."
-        "EqRequiredInTextDecl",         //  32, "The '=' character must follow \"{0}\" in the text declaration."
-        "QuoteRequiredInXMLDecl",       //  33, "The value following \"{0}\" in an XML declaration must be a quoted string."
-        "QuoteRequiredInTextDecl",      //  34, "The value following \"{0}\" in a text declaration must be a quoted string."
-        "InvalidCharInXMLDecl",         //  35, "An invalid XML character (Unicode: 0x{0}) was found in the XML declaration."
-        "InvalidCharInTextDecl",        //  36, "An invalid XML character (Unicode: 0x{0}) was found in the text declaration."
-        "VersionInfoInvalid",           //  37, "Invalid version \"{0}\"."
-        "VersionNotSupported",          //  38, "XML version \"{0}\" is not supported."
-        "SpaceRequiredInTextDecl",      //  39, "White space is required between the version and the encoding declaration."
-        "EncodingDeclInvalid",          //  40, "Invalid encoding name \"{0}\"."
-        "SDDeclInvalid",                //  41, "The standalone document declaration value must be \"yes\" or \"no\", not \"{0}\"."
-        "XMLDeclUnterminated",          //  42, "The XML declaration must end with \"?>\"."
-        "TextDeclUnterminated",         //  43, "The text declaration must end with \"?>\"."
-        "InvalidCharInInternalSubset",  //  44, "An invalid XML character (Unicode: 0x{0}) was found in the internal subset of the DTD."
-        "InvalidCharInExternalSubset",  //  45, "An invalid XML character (Unicode: 0x{0}) was found in the external subset of the DTD."
-        "InvalidCharInEntityValue",     //  46, "An invalid XML character (Unicode: 0x{0}) was found in the literal entity value."
-        "MixedContentUnterminated",     //  47, "The mixed content model \"(0}\" must end with \")*\"."
-        "NameRequiredInPEReference",    //  48, "The entity name must immediately follow the '%' in the parameter entity reference."
-        "SemicolonRequiredInPEReference", //  49, "The parameter entity reference must end with the ';' delimiter."
-        "ExternalIDRequired",           //  50, "The external entity declaration must begin with either \"SYSTEM\" or \"PUBLIC\"."
-        "PEReferenceWithinMarkup",      //  51, "The parameter entity reference \"%(0);\" cannot occur within markup in the internal subset of the DTD."
-        "InvalidCharInProlog",          //  52, "An invalid XML character (Unicode: 0x{0}) was found in the prolog of the document."
-        "InvalidCharInMisc",            //  53, "An invalid XML character (Unicode: 0x{0}) was found in markup after the end of the element content."
-        "InvalidCharInCDSect",          //  54, "An invalid XML character (Unicode: 0x{0}) was found in the CDATA section."
-        "InvalidCharInContent",         //  55, "An invalid XML character (Unicode: 0x{0}) was found in the element content of the document."
-        "ETagRequired",                 //  56, "The element type \"{0}\" must be terminated by the matching end-tag \"</{0}>\"."
-        "ETagUnterminated",             //  57, "The end-tag for element type \"{0}\" must end with a ''>'' delimiter."
-        "AttNameRequiredInAttDef",      //  58, "The attribute name must be specified in the attribute-list declaration for element \"{0}\"."
-        "AttTypeRequiredInAttDef",      //  59, "The attribute type must be specified in the attribute-list declaration of attribute \"{1}\" for element \"{0}\"."
-        "PubidCharIllegal",             //  60, "The character (Unicode: 0x{0}) is not permitted in the public identifier."
-        "EncodingNotSupported",         //  61, "The encoding \"{0}\" is not supported."
-        "EntityNotDeclared",            //  62, "The entity \"{0}\" was referenced, but not declared."
-        "ReferenceToUnparsedEntity",    //  63, "The unparsed entity reference \"&{0};\" is not permitted."
-        "ReferenceToExternalEntity",    //  64, "The external entity reference \"&{0};\" is not permitted in an attribute value."
-        "XMLLangInvalid",               //  65, "The xml:lang attribute value \"{0}\" is an invalid language identifier."
-        "CDSectUnterminated",           //  66, "The CDATA section must end with \"]]>\"."
-        "DuplicateTypeInMixedContent",  //  67, "The element type \"{0}\" was already specified in this content model."
-        "ElementEntityMismatch",        //  68, "The element \"{0}\" must start and end within the same entity."
-        "IDDefaultTypeInvalid",         //  69, "The ID attribute \"{0}\" must have a declared default of \"#IMPLIED\" or \"#REQUIRED\"."
-        "EncodingRequired",             //  70, "A parsed entity not encoded in either UTF-8 or UTF-16 must contain an encoding declaration."
-        "RecursiveReference",           //  71, "Recursive reference \"&{0};\". (Reference path: {1})"
-        "RecursivePEReference",         //  72, "Recursive reference \"%{0};\". (Reference path: {1})"
-        "ImproperDeclarationNesting",   //  73, "The replacement text of parameter entity \"(0)\" must include properly nested declarations."
-        "ImproperGroupNesting",         //  74, "The replacement text of parameter entity \"(0)\" must include properly nested pairs of parentheses in content model."
-        "IDInvalid",                    //  75, "Attribute value \"{1}\" of type ID must be a name."
-        "IDNotUnique",                  //  76, "Attribute value \"(1}\" of type ID must be unique within the document."
-        "IDREFInvalid",                 //  77, "Attribute value \"(1}\" of type IDREF must be a name."
-        "NMTOKENInvalid",               //  78, "Attribute value \"(1}\" of type NMTOKEN must be a name token."
-        "ENTITYInvalid",                //  79, "Attribute value \"(1}\" of type ENTITY must be the name of an unparsed entity."
-        "ENTITIESInvalid",              //  80, "Attribute value \"(1}\" of type ENTITIES must be the names of one or more unparsed entities."
-        "MSG_ELEMENT_WITH_ID_REQUIRED", //  81, "MSG_ELEMENT_WITH_ID_REQUIRED"
-        "MSG_ATTRIBUTE_NOT_DECLARED",   //  82, "MSG_ATTRIBUTE_NOT_DECLARED"
-        "MSG_ELEMENT_NOT_DECLARED",     //  83, "MSG_ELEMENT_NOT_DECLARED"
-        "MSG_AVAILABLE1",               //  84,
-        "MSG_DUPLICATE_ATTDEF",         //  85, "MSG_DUPLICATE_ATTDEF"
-        "MSG_MORE_THAN_ONE_ID_ATTRIBUTE", //  86, "MSG_MORE_THAN_ONE_ID_ATTRIBUTE"
-        "MSG_CONTENT_INVALID",          //  87, "MSG_CONTENT_INVALID"
-        "MSG_CONTENT_INCOMPLETE",       //  88, "MSG_CONTENT_INCOMPLETE"
-        "MSG_ELEMENT_ALREADY_DECLARED", //  89, "MSG_ELEMENT_ALREADY_DECLARED"
-        "MSG_ATTRIBUTE_VALUE_NOT_IN_LIST", //  90, "MSG_ATTRIBUTE_VALUE_NOT_IN_LIST"
-        "MSG_AVAILABLE2",               //  91,
-        "UndeclaredElementInContentSpec", //   92, "The content model of element \"{0}\" refers to the undeclared element \"{1}\"."
-        "MSG_FIXED_ATTVALUE_INVALID",   //  93, "MSG_FIXED_ATTVALUE_INVALID"
-        "MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED", //  94, "MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED"
-        "MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED", //  95, "MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED"
-        "MSG_AVAILABLE3",               //  96,
-        "MSG_AVAILABLE4",               //  97,
-        "MSG_CLOSE_PAREN_REQUIRED_IN_CHILDREN", //  98, "MSG_CLOSE_PAREN_REQUIRED_IN_CHILDREN"
-        "MSG_AVAILABLE5",               //  99,
-        "SystemIDUnterminated",         // 100, "MSG_SYSTEMID_UNTERMINATED"
-        "PublicIDUnterminated",         // 101, "MSG_PUBLICID_UNTERMINATED"
-        "MSG_EXTERNAL_ENTITY_NOT_PERMITTED", // 102, "MSG_EXTERNAL_ENTITY_NOT_PERMITTED"
-        "MSG_AVAILABLE6",               // 103,
-        "XMLDeclMustBeFirst",           // 104, "MSG_XMLDECL_MUST_BE_FIRST"
-        "TextDeclMustBeFirst",          // 105, "MSG_TEXTDECL_MUST_BE_FIRST"
-        "ElementDeclUnterminated",      // 106, "MSG_ELEMENTDECL_UNTERMINATED"
-        "MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_PEDECL",     // 107, "MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_PEDECL"
-        "MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_ENTITYDECL",     // 108, "MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_ENTITYDECL"
-        "MSG_SPACE_REQUIRED_BEFORE_PERCENT_IN_PEDECL",     // 109, "MSG_SPACE_REQUIRED_BEFORE_PERCENT_IN_PEDECL"
-        "MSG_ENTITY_NAME_REQUIRED_IN_ENTITYDECL",     // 110, "MSG_ENTITY_NAME_REQUIRED_IN_ENTITYDECL"
-        "MSG_SPACE_REQUIRED_AFTER_ENTITY_NAME_IN_ENTITYDECL",     // 111, "MSG_SPACE_REQUIRED_AFTER_ENTITY_NAME_IN_ENTITYDECL"
-        "EntityDeclUnterminated",       // 112, "MSG_ENTITYDECL_UNTERMINATED"
-        "MSG_NOTATION_NAME_REQUIRED_FOR_UNPARSED_ENTITYDECL",     // 113, "MSG_NOTATION_NAME_REQUIRED_FOR_UNPARSED_ENTITYDECL"
-        "MSG_NOTATION_NOT_DECLARED_FOR_UNPARSED_ENTITYDECL",     // 114, "MSG_NOTATION_NOT_DECLARED_FOR_UNPARSED_ENTITYDECL"
-        "MSG_NAME_REQUIRED_IN_NOTATIONTYPE",     // 115, "MSG_NAME_REQUIRED_IN_NOTATIONTYPE"
-        "MSG_NMTOKEN_REQUIRED_IN_ENUMERATION",     // 116, "MSG_NMTOKEN_REQUIRED_IN_ENUMERATION"
-        "MSG_NOTATION_NOT_DECLARED_FOR_NOTATIONTYPE_ATTRIBUTE",     // 117, "MSG_NOTATION_NOT_DECLARED_FOR_NOTATIONTYPE_ATTRIBUTE"
-        "NotationTypeUnterminated",     // 118, "MSG_NOTATIONTYPE_UNTERMINATED"
-        "EnumerationUnterminated",      // 119, "MSG_ENUMERATION_UNTERMINATED"
-        "MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL", // 120, "MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL"
-        "MSG_MORE_THAN_ONE_NOTATION_ATTRIBUTE", // 121, "MSG_MORE_THAN_ONE_NOTATION_ATTRIBUTE"
-        "NotationDeclUnterminated",     // 122, "MSG_NOTATIONDECL_UNTERMINATED"
-        "MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE",     // 123, "MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE"
-        "CDEndInContent",               // 124, "MSG_CDEND_IN_CONTENT"
-        "MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL",     // 125, "MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL"
-        "TwoColonsInQName",             // 126, ""
-        "MarkupNotRecognizedInContent", // 127, "MSG_MARKUP_NOT_RECOGNIZED_IN_CONTENT"
-        "MarkupNotRecognizedInMisc",    // 128, "MSG_MARKUP_NOT_RECOGNIZED_IN_MISC"
-        "MarkupNotRecognizedInProlog",  // 129, "MSG_MARKUP_NOT_RECOGNIZED_IN_PROLOG"
-        "MSG_OPEN_PAREN_REQUIRED_IN_NOTATIONTYPE",     // 130, "MSG_OPEN_PAREN_REQUIRED_IN_NOTATIONTYPE"
-        "PITargetRequired",             // 131, "MSG_PITARGET_REQUIRED"
-        "MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE",     // 132, "MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE"
-        "MSG_URI_FRAGMENT_IN_SYSTEMID", // 133, "MSG_URI_FRAGMENT_IN_SYSTEMID"
-        "RootElementRequired",          // 134, "MSG_ROOT_ELEMENT_REQUIRED"
-        "MSG_SPACE_REQUIRED_AFTER_FIXED_IN_DEFAULTDECL",     // 135, "MSG_SPACE_REQUIRED_AFTER_FIXED_IN_DEFAULTDECL"
-        "MSG_SPACE_REQUIRED_AFTER_NOTATION_IN_NOTATIONTYPE",     // 136, "MSG_SPACE_REQUIRED_AFTER_NOTATION_IN_NOTATIONTYPE"
-        "MSG_SPACE_REQUIRED_AFTER_NOTATION_NAME_IN_NOTATIONDECL",     // 137, "MSG_SPACE_REQUIRED_AFTER_NOTATION_NAME_IN_NOTATIONDECL"
-        "MSG_SPACE_REQUIRED_BEFORE_ATTRIBUTE_NAME_IN_ATTDEF",     // 138, "MSG_SPACE_REQUIRED_BEFORE_ATTRIBUTE_NAME_IN_ATTDEF"
-        "MSG_SPACE_REQUIRED_BEFORE_ATTTYPE_IN_ATTDEF",     // 139, "MSG_SPACE_REQUIRED_BEFORE_ATTTYPE_IN_ATTDEF"
-        "MSG_SPACE_REQUIRED_BEFORE_DEFAULTDECL_IN_ATTDEF",     // 140, "MSG_SPACE_REQUIRED_BEFORE_DEFAULTDECL_IN_ATTDEF"
-        "MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ATTLISTDECL",     // 141, "MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ATTLISTDECL"
-        "MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_NOTATIONDECL",     // 142, "MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_NOTATIONDECL"
-        "MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE",     // 143, "MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE"
-        "MSG_XML_SPACE_DECLARATION_ILLEGAL",     // 144, "MSG_XML_SPACE_DECLARATION_ILLEGAL"
-        "MSG_CLOSE_PAREN_REQUIRED_IN_MIXED",     // 145, "MSG_CLOSE_PAREN_REQUIRED_IN_MIXED"
-        "MSG_CONTENTSPEC_REQUIRED_IN_ELEMENTDECL",     // 146, "MSG_CONTENTSPEC_REQUIRED_IN_ELEMENTDECL"
-        "DoctypedeclUnterminated", // 147, "MSG_DOCTYPEDECL_UNTERMINATED"
-        "MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL",     // 148, "MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL"
-        "MSG_ELEMENT_TYPE_REQUIRED_IN_MIXED_CONTENT",     // 149, "MSG_ELEMENT_TYPE_REQUIRED_IN_MIXED_CONTENT"
-        "MSG_MARKUP_NOT_RECOGNIZED_IN_DTD",     // 150, "MSG_MARKUP_NOT_RECOGNIZED_IN_DTD"
-        "AttributeValueUnterminated",   // 151, "MSG_ATTRIBUTE_VALUE_UNTERMINATED"
-        "MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN",     // 152, "MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN"
-        "MSG_ROOT_ELEMENT_TYPE_REQUIRED",     // 153, "MSG_ROOT_ELEMENT_TYPE_REQUIRED"
-        "MSG_SPACE_REQUIRED_AFTER_PUBIDLITERAL_IN_EXTERNALID",     // 154, "MSG_SPACE_REQUIRED_AFTER_PUBIDLITERAL_IN_EXTERNALID"
-        "MSG_SPACE_REQUIRED_BEFORE_CONTENTSPEC_IN_ELEMENTDECL",     // 155, "MSG_SPACE_REQUIRED_BEFORE_CONTENTSPEC_IN_ELEMENTDECL"
-        "MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ELEMENTDECL",     // 156, "MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ELEMENTDECL"
-        "MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_UNPARSED_ENTITYDECL",     // 157, "MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_UNPARSED_ENTITYDECL"
-        "MSG_SPACE_REQUIRED_BEFORE_PUBIDLITERAL_IN_EXTERNALID",     // 158, "MSG_SPACE_REQUIRED_BEFORE_PUBIDLITERAL_IN_EXTERNALID"
-        "MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL",     // 159, "MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL"
-        "MSG_SPACE_REQUIRED_BEFORE_SYSTEMLITERAL_IN_EXTERNALID",     // 160, "MSG_SPACE_REQUIRED_BEFORE_SYSTEMLITERAL_IN_EXTERNALID"
-        "ReferenceNotInOneEntity",      // 161, "MSG_REFERENCE_NOT_IN_ONE_ENTITY"
-        "CommentNotInOneEntity",        // 162, "MSG_COMMENT_MUST_BEGIN_AND_END_IN_THE_SAME_ENTITY"
-        "CommentUnterminated",          // 163, "MSG_COMMENT_UNTERMINATED"
-        "PIUnterminated",               // 164, "MSG_PI_UNTERMINATED"
-        "PINotInOneEntity",             // 165, "MSG_PI_MUST_BEGIN_AND_END_IN_THE_SAME_ENTITY"
-        "ReferenceUnterminated",        // 166, "MSG_REFERENCE_UNTERMINATED"
-        "PrefixDeclared",               // 167, "MSG_PREFIX_DECLARED"
-        "MSG_ATT_DEFAULT_INVALID",      // 168, "MSG_ATT_DEFAULT_INVALID"
-        "MSG_GENERIC_SCHEMA_ERROR",     // 169  "MSG_GENERIC_SCHEMA_ERROR"
-
-        // ...
-        ""                              //
-    };
-
-    public static final int
-        VC_ROOT_ELEMENT_TYPE = 1,           // 2.8 VC: Root Element Type
-        VC_IDREF = 2,                       // 3.3.1 VC: IDREF
-        VC_NAME_TOKEN = 3,                  // 3.3.1 VC: Name Token
-        P17_RESERVED_PITARGET = 4,          // 2.6 [17] PITarget matching [Xx][Mm][Ll] is reserved
-        P16_WHITESPACE_REQUIRED = 5,        // 2.6 [16] White space required between PITarget and data
-        P16_INVALID_CHARACTER = 6,          // 2.6 [16] Invalid character in PI data
-        P15_DASH_DASH = 7,                  // 2.5 [15] The string "--" must not occur within comments
-        P15_INVALID_CHARACTER = 8,          // 2.5 [15] Invalid character in comment
-        WFC_LEGAL_CHARACTER = 9,            // 4.1 [66] WFC: Legal Character
-        P10_INVALID_CHARACTER = 10,         // 2.3 [10] Invalid character in AttValue
-        WFC_NO_LESSTHAN_IN_ATTVALUE = 11,   // 3.1 [41] WFC: No < in Attribute Values
-        P10_QUOTE_REQUIRED = 12,             // 2.3 [10] No quote delimiter in AttValue
-        P68_NAME_REQUIRED = 13,              // 4.1 [68] Name missing in EntityRef
-        P68_SEMICOLON_REQUIRED = 14,         // 4.1 [68] An EntityRef must end with a ';'
-        P66_DIGIT_REQUIRED = 15,             // 4.1 [66] A "&#" CharRef must contain at least one decimal digit
-        P66_HEXDIGIT_REQUIRED = 16,          // 4.1 [66] A "&#x" CharRef must contain at least one hexadecimal digit
-        P66_SEMICOLON_REQUIRED = 17,         // 4.1 [66] A CharRef must end with a ';'
-        P11_QUOTE_REQUIRED = 18,             // 2.3 [11] No quote delimiter in SystemLiteral
-        P11_INVALID_CHARACTER = 19,         // 2.3 [11] Invalid character in SystemLiteral
-        P12_QUOTE_REQUIRED = 20,             // 2.3 [12] No quote delimiter in PubidLiteral
-        P12_INVALID_CHARACTER = 21,         // 2.3 [12] Invalid character in PubidLiteral
-        P62_UNTERMINATED = 22,              // 3.4 [62] Included conditional sections must end with "]]>"
-        P63_UNTERMINATED = 23,              // 3.4 [63] Excluded conditional sections must end with "]]>"
-        P65_INVALID_CHARACTER = 24,         // 3.4 [64] Invalid character in excluded conditional section
-        P40_UNTERMINATED = 25,              // 3.1 [40] Element type must be followed by attributes, ">" or "/>"
-        P41_EQ_REQUIRED = 26,                // 3.1 [41] Attribute name must be followed by an '=' character
-        WFC_UNIQUE_ATT_SPEC = 27,           // 3.1 [40] [44] Attribute must only appear once
-        P77_ENCODINGDECL_REQUIRED = 28,      // 4.3.1 [77] The encoding declaration is not optional
-        P23_VERSIONINFO_REQUIRED = 29,       // 2.8 [23] The version is not optional
-        P24_EQ_REQUIRED = 30,                // 2.8 [24] An '=' is required after the version
-        P32_EQ_REQUIRED = 31,                // 2.9 [32] An '=' is required in a standalone document declaration
-        P80_EQ_REQUIRED = 32,                // 4.3.3 [80] An '=' is required in an encoding declaration
-        P24_QUOTE_REQUIRED = 33,             // 2.8 [24] The version is a quoted string
-        P32_QUOTE_REQUIRED = 34,             // 2.9 [32] The standalone document declaration value is a quoted string
-        P80_QUOTE_REQUIRED = 35,             // 4.3.3 [80] The encoding name value is a quoted string
-        P26_INVALID_CHARACTER = 36,         // 2.8 [26] The version contained an invalid XML character
-        P32_INVALID_CHARACTER = 37,         // 2.9 [32] The standalone document declaration value contained an invalid XML character
-        P81_INVALID_CHARACTER = 38,         // 4.3.3 [81] The encoding name value contained an invalid XML character
-        P26_INVALID_VALUE = 39,             // 2.8 [26] The version was not in the correct format
-        P26_NOT_SUPPORTED = 40,             // 2.8 [26] The version specified is not supported
-        P80_WHITESPACE_REQUIRED = 41,       // 4.3.3 [80] Whitespace required between version and encoding
-        P81_INVALID_VALUE = 42,             // 4.3.3 [81] The encoding name value was not in the correct format
-        P32_INVALID_VALUE = 43,             // 2.9 [32] The standalone document declaration value was not "yes" or "no"
-        P23_UNTERMINATED = 44,              // 2.8 [23] An XML declaration must end with "?>"
-        P77_UNTERMINATED = 45,              // 4.3.1 [77] A text declaration must end with "?>"
-        P28_INVALID_CHARACTER = 46,         // 2.8 [28] Invalid character in the internal subset of the DTD
-        P30_INVALID_CHARACTER = 47,         // 2.8 [30] Invalid character in the external subset or an external entity within DTD
-        P9_INVALID_CHARACTER = 48,          // 2.3 [9] Invalid character in EntityValue
-        P51_UNTERMINATED = 49,              // 3.2.2 [51] Mixed content model with element types must end with ")*"
-        P69_NAME_REQUIRED = 50,              // 4.1 [69] Name missing in PEReference
-        P69_SEMICOLON_REQUIRED = 51,         // 4.1 [69] An PEReference must end with a ';'
-        P75_INVALID = 52,                   // 4.2.2 [75] An ExternalId must begin with either "SYSTEM" or "PUBLIC"
-        WFC_PES_IN_INTERNAL_SUBSET = 53,    // 2.8 [28] PEReferences in the internal subset cannot occur within markup declarations
-        P22_INVALID_CHARACTER = 54,         // 2.8 [22] Invalid character in prolog
-        P27_INVALID_CHARACTER = 55,         // 2.8 [27] Invalid character in Misc
-        P20_INVALID_CHARACTER = 56,         // 2.7 [20] Invalid character in CDSect
-        P43_INVALID_CHARACTER = 57,         // 3.1 [43] Invalid character in content
-        P39_UNTERMINATED = 58,              // 3 [39] Element type must be followed by attributes, ">" or "/>"
-        P42_UNTERMINATED = 59,              // 3.1 [42] end-tag must end with '>'
-        P81_NOT_SUPPORTED = 60,             // 4.3.3 [81] The encoding is not supported
-        WFC_ENTITY_DECLARED = 61,           // 4.1 [68] The entity was referenced, but not declared
-        VC_ENTITY_DECLARED = 62,            // 4.1 [68] The entity was referenced, but not declared
-        WFC_PARSED_ENTITY = 63,             // 4.1 [68] An unparsed entity was referenced
-        WFC_NO_EXTERNAL_ENTITY_REFERENCES = 64, // 3.1 [42] reference to external entity in AttValue
-        P33_INVALID = 65,                   // 2.12 [33] xml:lang attribute value must match LanguageID production
-        P18_UNTERMINATED = 66,              // 2.7 [18] CDATA sections must end with "]]>"
-        VC_NO_DUPLICATE_TYPES = 67,         // 3.2.2 [51] The same type must not appear more than once in a mixed content declaration
-        P78_NOT_WELLFORMED = 68,            // 4.3.2 [78] 
-        VC_ID_ATTRIBUTE_DEFAULT = 69,       // 3.3.1 [54] 
-        P53_NAME_REQUIRED = 70,              // 3.3 [53] 
-        P53_ATTTYPE_REQUIRED = 71,           // 3.3 [53] 
-        P81_REQUIRED = 72,                  // 4.3.3 [81] 
-        WFC_NO_RECURSION = 73,              // 4.1 [68] 
-        VC_PROPER_DECLARATION_PE_NESTING = 74, // 2.8 [29] 
-        VC_PROPER_GROUP_PE_NESTING = 75,    // 3.2.1 [47] 
-        VC_ID = 76,                         // 3.3.1 [56] 
-        VC_ENTITY_NAME = 77,                // 3.3.1 [56] 
-        VC_ATTRIBUTE_VALUE_TYPE = 78,       // 3.1 [41] 
-        VC_ELEMENT_VALID = 79,              // 3 [39] 
-        VC_STANDALONE_DOCUMENT_DECLARATION = 80, // 2.9 [32] 
-        VC_ONE_ID_PER_ELEMENT_TYPE = 81,    // 3.3.1 [56] 
-        VC_UNIQUE_ELEMENT_TYPE_DECLARATION = 82, // 3.2 [45] 
-        P45_UNDECLARED_ELEMENT_IN_CONTENTSPEC = 83, // 3.2 [45] 
-
-        VC_NOTATION_ATTRIBUTES = 84,
-        P53_DUPLICATE = 85,
-        VC_ENUMERATION = 86,
-        VC_FIXED_ATTRIBUTE_DEFAULT = 87,
-        VC_REQUIRED_ATTRIBUTE = 88,
-        VC_NOTATION_DECLARED = 89,
-        P58_NAME_REQUIRED = 90,
-        P58_UNTERMINATED = 91,
-        P59_NMTOKEN_REQUIRED = 92,
-        P59_UNTERMINATED = 93,
-        P70_SPACE = 94,
-        P70_REQUIRED_NAME = 95,
-        P70_REQUIRED_SPACE = 96,
-        P71_UNTERMINATED = 97,
-        P72_SPACE = 98,
-        P72_UNTERMINATED = 99,
-        P76_REQUIRED = 100,
-        P82_NAME_REQUIRED = 101,
-        P82_SPACE_REQUIRED = 102,
-        P82_UNTERMINATED = 103,
-        P14_INVALID = 104,
-        P16_PITARGET_REQUIRED = 105,
-        P16_REQUIRED = 106,
-        P1_ELEMENT_REQUIRED = 107,
-        P22_NOT_RECOGNIZED = 108,
-        P27_NOT_RECOGNIZED = 109,
-        P43_NOT_RECOGNIZED = 110,
-        P52_ELEMENT_TYPE_REQUIRED = 111,
-        P52_SPACE_REQUIRED = 112,
-        P53_SPACE_REQUIRED = 113,
-        P58_OPEN_PAREN_REQUIRED = 114,
-        P58_SPACE_REQUIRED = 115,
-        P60_SPACE_REQUIRED = 116,
-        S2_10_DECLARATION_ILLEGAL = 117,
-        P39_ELEMENT_TYPE_REQUIRED = 118,
-        P28_ROOT_ELEMENT_TYPE_REQUIRED = 119,
-        P28_SPACE_REQUIRED = 120,
-        P28_UNTERMINATED = 121,
-        P29_NOT_RECOGNIZED = 122,
-        P45_CONTENTSPEC_REQUIRED = 123,
-        P45_ELEMENT_TYPE_REQUIRED = 124,
-        P45_SPACE_REQUIRED = 125,
-        P45_UNTERMINATED = 126,
-        P47_CLOSE_PAREN_REQUIRED = 127,
-        P47_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED = 128,
-        P51_CLOSE_PAREN_REQUIRED = 129,
-        P51_ELEMENT_TYPE_REQUIRED = 130,
-        P75_SPACE_REQUIRED = 131,
-        P76_SPACE_REQUIRED = 132,
-        P15_UNTERMINATED = 133,
-        P16_UNTERMINATED = 134,
-        P67_UNTERMINATED = 135,
-        P10_UNTERMINATED = 136,
-        P22_XMLDECL_MUST_BE_FIRST = 137,
-        P30_TEXTDECL_MUST_BE_FIRST = 138,
-        P5_INVALID_CHARACTER = 139,
-        P11_UNTERMINATED = 140,
-        P12_UNTERMINATED = 141,
-        P11_URI_FRAGMENT = 142,
-        VC_ONE_NOTATION_PER_ELEMENT_TYPE = 143,
-        NC_PREFIX_DECLARED = 144,
-        VC_ATTRIBUTE_DEFAULT_LEGAL = 145,
-        SCHEMA_GENERIC_ERROR = 146,
-
-        // ...
-        CONSTRAINT_MAX_CODE = 200;
-
-/*
-    private static final Constraint[] fgConstraints = {
-        new Constraint(null, null, null, null),
-    // VC_ROOT_ELEMENT_TYPE = 1
-        new Constraint("2.8", "", "2.8 VC: Root Element Type",
-                       "Validity Constraint: Root Element Type\n" +
-                       "The Name in the document type declaration must match the element type of the\n" +
-                       "root element."),
-    // VC_IDREF = 2
-        new Constraint("3.3.1 2.3", "[56] [6]", "3.3.1 VC: IDREF",
-                       "Validity Constraint: IDREF\n" +
-                       "[56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'\n" +
-                       "Values of type IDREF must match the Name production, and values of type\n" +
-                       "IDREFS must match Names; each Name must match the value of an ID attribute\n" +
-                       "on some element in the XML document; i.e. IDREF values must match the value\n" +
-                       "of some ID attribute."),
-    // VC_NAME_TOKEN = 3
-        new Constraint("3.3.1 2.3", "[56] [8]", "3.3.1 VC: Name Token",
-                       "Validity Constraint: Name Token\n" +
-                       "Values of type NMTOKEN must match the Nmtoken production; values of type\n" +
-                       "NMTOKENS must match Nmtokens."),
-    // P17_RESERVED_PITARGET = 4
-        new Constraint("2.6", "[17]", "2.6 [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))",
-                       "[17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))\n" +
-                       "The target names \"XML\", \"xml\", and so on are reserved for standardization\n" +
-                       "in this or future versions of this specification."),
-    // P16_WHITESPACE_REQUIRED = 5
-        new Constraint("2.6 2.3", "[16] [3]", "2.6 [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'",
-                       "[16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'\n" +
-                       "[3] S ::= (#x20 | #x9 | #xD | #xA)+\n" +
-                       "White space is required between the PITarget and any additional characters\n" +
-                       "that are to be passed through to the application."),
-    // P16_INVALID_CHARACTER = 6
-        new Constraint("2.6 2.2", "[16] [2]", "2.6 [2] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'",
-                       "[16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'\n" +
-                       "[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]\n" +
-                       "Processing instruction data is required to contain legal XML characters."),
-    // P15_DASH_DASH = 7
-        new Constraint("2.5", "[15]", "2.5 [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'",
-                       "[15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'\n" +
-                       "For compatibility, the string \"--\" (double-hyphen) must not occur within comments."),
-    // P15_INVALID_CHARACTER = 8
-        new Constraint("2.5 2.2", "[15] [2]", "2.5 [2] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'",
-                       "[15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'\n" +
-                       "[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]\n" +
-                       "Comments are required to contain legal XML characters."),
-    // WFC_LEGAL_CHARACTER = 9
-        new Constraint("4.1", "[66] [2]", "4.1 WFC: Legal Character",
-                       "Well-Formedness Constraint: Legal Character\n" +
-                       "[66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'\n" +
-                       "[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]\n" +
-                       "Characters referred to using character references must match the production\n" +
-                       "for Char."),
-    // P10_INVALID_CHARACTER = 10
-        new Constraint("2.3", "[10]", "2.3 [10] AttValue ::= '\"' ([^<&\"] | Reference)* '\"' | \"'\" ([^<&'] | Reference)* \"'\"",
-                       "[10] AttValue ::= '\"' ([^<&\"] | Reference)* '\"' | \"'\" ([^<&'] | Reference)* \"'\"\n" +
-                       "Attribute values are required to contain legal XML characters."),
-    // WFC_NO_LESSTHAN_IN_ATTVALUE = 11
-        new Constraint("3.1 2.3", "[41] [10]", "3.1 WFC: No < in Attribute Values",
-                       "Well-Formedness Constraint: No < in Attribute Values\n" +
-                       "[41] Attribute ::= Name Eq AttValue\n" +
-                       "[10] AttValue ::= '\"' ([^<&\"] | Reference)* '\"' | \"'\" ([^<&'] | Reference)* \"'\"\n" +
-                       "The replacement text of any entity referred to directly or indirectly in an\n" +
-                       "attribute value (other than \"&lt;\") must not contain a <."),
-    // P10_QUOTE_REQUIRED = 12
-        new Constraint("2.3", "[10]", "2.3 [10] AttValue ::= '\"' ([^<&\"] | Reference)* '\"' | \"'\" ([^<&'] | Reference)* \"'\"",
-                       "[10] AttValue ::= '\"' ([^<&\"] | Reference)* '\"' | \"'\" ([^<&'] | Reference)* \"'\"\n" +
-                       "Attribute values are specified using quoted strings."),
-    // P68_NAME_REQUIRED = 13
-        new Constraint("4.1", "[68]", "4.1 [68] EntityRef ::= '&' Name ';'",
-                       "[68] EntityRef ::= '&' Name ';'\n" +
-                       "The '&' delimiter must be followed by a valid Name in an entity reference."),
-    // P68_SEMICOLON_REQUIRED = 14
-        new Constraint("4.1", "[68]", "4.1 [68] EntityRef ::= '&' Name ';'",
-                       "[68] EntityRef ::= '&' Name ';'\n" +
-                       "An entity reference must end with a ';' delimiter."),
-    // P66_DIGIT_REQUIRED = 15
-        new Constraint("4.1", "[66]", "4.1 [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'",
-                       "[66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'\n" +
-                       "If the character reference begins with \"&#\", not \"&#x\", the digits up\n" +
-                       "to the terminating ; provide a decimal representation of the character's\n" +
-                       "code point in ISO/IEC 10646."),
-    // P66_HEXDIGIT_REQUIRED = 16
-        new Constraint("4.1", "[66]", "4.1 [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'",
-                       "[66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'\n" +
-                       "If the character reference begins with \"&#x\", the digits and letters up to\n" +
-                       "the terminating ; provide a hexadecimal representation of the character's\n" +
-                       "code point in ISO/IEC 10646."),
-    // P66_SEMICOLON_REQUIRED = 17
-        new Constraint("4.1", "[66]", "4.1 [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'",
-                       "[66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'\n" +
-                       "A character reference must end with a ';' delimiter."),
-    // P11_QUOTE_REQUIRED = 18
-        new Constraint("2.3", "[11]", "2.3 [11] SystemLiteral ::= ('\"' [^\"]* '\"') | (\"'\" [^']* \"'\")",
-                       "[11] SystemLiteral ::= ('\"' [^\"]* '\"') | (\"'\" [^']* \"'\")\n" +
-                       "System identifiers are specified using quoted strings."),
-    // P11_INVALID_CHARACTER = 19
-        new Constraint("2.3", "[11]", "2.3 [11] SystemLiteral ::= ('\"' [^\"]* '\"') | (\"'\" [^']* \"'\")",
-                       "[11] SystemLiteral ::= ('\"' [^\"]* '\"') | (\"'\" [^']* \"'\")\n" +
-                       "System identifiers are required to contain legal XML characters."),
-    // P12_QUOTE_REQUIRED = 20
-        new Constraint("2.3", "[12]", "2.3 [12] PubidLiteral ::= '\"' PubidChar* '\"' | \"'\" (PubidChar - \"'\")* \"'\"",
-                       "[12] PubidLiteral ::= '\"' PubidChar* '\"' | \"'\" (PubidChar - \"'\")* \"'\"\n" +
-                       "Public identifiers are specified using quoted strings."),
-    // P12_INVALID_CHARACTER = 21
-        new Constraint("2.3", "[13]", "2.3 [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]",
-                       "[13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]\n" +
-                       "Public identifiers must consist of PubidChar characters."),
-    // P62_UNTERMINATED = 22
-        new Constraint("3.4", "[62]", "3.4 [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'",
-                       "[62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'\n" +
-                       "Included conditional section must be terminated by \"]]>\"."),
-    // P63_UNTERMINATED = 23
-        new Constraint("3.4", "[63]", "3.4 [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'",
-                       "[63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'\n" +
-                       "Excluded conditional sections must be terminated by \"]]>\"."),
-    // P65_INVALID_CHARACTER = 24
-        new Constraint("3.4", "[65]", "3.4 [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)",
-                       "[65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)\n" +
-                       "Excluded conditional sections are required to contain legal XML characters."),
-    // P40_UNTERMINATED = 25
-        new Constraint("3.1", "[40]", "3.1 [40] STag ::= '<' Name (S Attribute)* S? '>'",
-                       "[40] STag ::= '<' Name (S Attribute)* S? '>'\n" +
-                       "[39] element ::= EmptyElemTag | STag content ETag\n" +
-                       "[44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'\n" +
-                       "Element type name must be followed by Attribute, \">\" or \"/>\"."),
-    // P41_EQ_REQUIRED = 26
-        new Constraint("3.1", "[41]", "3.1 [41] Attribute ::= Name Eq AttValue",
-                       "[41] Attribute ::= Name Eq AttValue\n" +
-                       "[25] Eq ::= S? '=' S?\n" +
-                       "Attribute name must be followed by an '=' character."),
-    // WFC_UNIQUE_ATT_SPEC = 27
-        new Constraint("3.1", "[40] [44]", "3.1 WFC: Unique Att Spec",
-                       "Well-Formedness Constraint: Unique Att Spec\n" +
-                       "[40] STag ::= '<' Name (S Attribute)* S? '>'\n" +
-                       "[44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'\n" +
-                       "No attribute name may appear more than once in the same start-tag or\n" +
-                       "empty-element tag."),
-    // P77_ENCODINGDECL_REQUIRED = 28
-        new Constraint("4.3.1", "[77]", "4.3.1 [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'",
-                       "[77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'\n" +
-                       "The encoding declaration is required in a text declaration."),
-    // P23_VERSIONINFO_REQUIRED = 29
-        new Constraint("2.8", "[23]", "2.8 [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'",
-                       "[23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'\n" +
-                       "The version is required in an XML declaration."),
-    // P24_EQ_REQUIRED = 30
-        new Constraint("2.8", "[24]", "2.8 [24] VersionInfo ::= S 'version' Eq (\"'\" VersionNum \"'\" | '\"' VersionNum '\"')",
-                       "[24] VersionInfo ::= S 'version' Eq (\"'\" VersionNum \"'\" | '\"' VersionNum '\"')\n" +
-                       "[25] Eq ::= S? '=' S?\n" +
-                       "The '=' character must follow \"version\" in VersionInfo."),
-    // P32_EQ_REQUIRED = 31
-        new Constraint("2.9", "[32]", "2.9 [32] SDDecl ::= S 'standalone' Eq (\"'\" ('yes' | 'no') \"'\" | '\"' ('yes' | 'no') '\"')",
-                       "[32] SDDecl ::= S 'standalone' Eq (\"'\" ('yes' | 'no') \"'\" | '\"' ('yes' | 'no') '\"')\n" +
-                       "[25] Eq ::= S? '=' S?\n" +
-                       "The '=' character must follow \"standalone\" in SDDecl."),
-    // P80_EQ_REQUIRED = 32
-        new Constraint("4.3.3", "[80]", "4.3.3 [80] EncodingDecl ::= S 'encoding' Eq ('\"' EncName '\"' | \"'\" EncName \"'\")",
-                       "[80] EncodingDecl ::= S 'encoding' Eq ('\"' EncName '\"' | \"'\" EncName \"'\")\n" +
-                       "[25] Eq ::= S? '=' S?\n" +
-                       "The '=' character must follow \"encoding\" in EncodingDecl."),
-    // P24_QUOTE_REQUIRED = 33
-        new Constraint("2.8", "[24]", "2.8 [24] VersionInfo ::= S 'version' Eq (\"'\" VersionNum \"'\" | '\"' VersionNum '\"')",
-                       "[24] VersionInfo ::= S 'version' Eq (\"'\" VersionNum \"'\" | '\"' VersionNum '\"')\n" +
-                       "The version is specified using a quoted string."),
-    // P32_QUOTE_REQUIRED = 34
-        new Constraint("2.9", "[32]", "2.9 [32] SDDecl ::= S 'standalone' Eq (\"'\" ('yes' | 'no') \"'\" | '\"' ('yes' | 'no') '\"')",
-                       "[32] SDDecl ::= S 'standalone' Eq (\"'\" ('yes' | 'no') \"'\" | '\"' ('yes' | 'no') '\"')\n" +
-                       "The standalone document declaration value is specified using a quoted string."),
-    // P80_QUOTE_REQUIRED = 35
-        new Constraint("4.3.3", "[80]", "4.3.3 [80] EncodingDecl ::= S 'encoding' Eq ('\"' EncName '\"' | \"'\" EncName \"'\")",
-                       "[80] EncodingDecl ::= S 'encoding' Eq ('\"' EncName '\"' | \"'\" EncName \"'\")\n" +
-                       "The encoding name value is specified using a quoted string."),
-    // P26_INVALID_CHARACTER = 36
-        new Constraint("2.8", "[26]", "2.8 [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+",
-                       "[26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+\n" +
-                       "The version is required to contain legal XML characters.."),
-    // P32_INVALID_CHARACTER = 37
-        new Constraint("2.9", "[32]", "2.9 [32] SDDecl ::= S 'standalone' Eq (\"'\" ('yes' | 'no') \"'\" | '\"' ('yes' | 'no') '\"')",
-                       "[32] SDDecl ::= S 'standalone' Eq (\"'\" ('yes' | 'no') \"'\" | '\"' ('yes' | 'no') '\"')\n" +
-                       "The standalone document declaration value is required to contain legal XML characters."),
-    // P81_INVALID_CHARACTER = 38
-        new Constraint("4.3.3", "[81]", "4.3.3 [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*",
-                       "[81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*\n" +
-                       "The encoding name value is required to contain legal XML characters."),
-    // P26_INVALID_VALUE = 39
-        new Constraint("2.8", "[26]", "2.8 [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+",
-                       "[26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+\n" +
-                       "The version value must match the production for VersionNum."),
-    // P26_NOT_SUPPORTED = 40
-        new Constraint("2.8", "[26]", "2.8 [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+",
-                       "[26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+\n" +
-                       "Processors may signal an error if they receive documents labeled with versions\n" +
-                       "they do not support."),
-    // P80_WHITESPACE_REQUIRED = 41
-        new Constraint("4.3.3", "[80]", "4.3.3 [80] EncodingDecl ::= S 'encoding' Eq ('\"' EncName '\"' | \"'\" EncName \"'\")",
-                       "[80] EncodingDecl ::= S 'encoding' Eq ('\"' EncName '\"' | \"'\" EncName \"'\")\n" +
-                       "Whitespace is required between the version and the encoding declaration."),
-    // P81_INVALID_VALUE = 42
-        new Constraint("4.3.3", "[81]", "4.3.3 [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*",
-                       "[81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*\n" +
-                       "The encoding name value must match the production for EncName."),
-    // P32_INVALID_VALUE = 43
-        new Constraint("2.9", "[32]", "2.9 [32] SDDecl ::= S 'standalone' Eq (\"'\" ('yes' | 'no') \"'\" | '\"' ('yes' | 'no') '\"')",
-                       "[32] SDDecl ::= S 'standalone' Eq (\"'\" ('yes' | 'no') \"'\" | '\"' ('yes' | 'no') '\"')\n" +
-                       "The standalone document declaration must have a value of \"yes\" or \"no\"."),
-    // P23_UNTERMINATED = 44
-        new Constraint("2.8", "[23]", "2.8 [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'",
-                       "[23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'\n" +
-                       "The XML declaration must be terminated by \"?>\"."),
-    // P77_UNTERMINATED = 45
-        new Constraint("4.3.1", "[77]", "4.3.1 [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'",
-                       "[77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'\n" +
-                       "The text declaration must be terminated by \"?>\"."),
-    // P28_INVALID_CHARACTER = 46
-        new Constraint("2.8", "[28]", "2.8 [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' (markupdecl | PEReference | S)* ']' S?)? '>'",
-                       "[28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' (markupdecl | PEReference | S)* ']' S?)? '>'\n" +
-                       "The internal subset of the DTD is required to contain legal XML characters."),
-    // P30_INVALID_CHARACTER = 47
-        new Constraint("2.8", "[30]", "2.8 [30] extSubset ::= TextDecl? extSubsetDecl",
-                       "[30] extSubset ::= TextDecl? extSubsetDecl\n" +
-                       "[31] extSubsetDecl ::= ( markupdecl | conditionalSect | PEReference | S )*\n" +
-                       "External entities in the DTD are required to contain legal XML characters."),
-    // P9_INVALID_CHARACTER = 48
-        new Constraint("2.3", "[9]", "2.3 [9] EntityValue ::= '\"' ([^%&\"] | PEReference | Reference)* '\"' | \"'\" ([^%&'] | PEReference | Reference)* \"'\"",
-                       "[9] EntityValue ::= '\"' ([^%&\"] | PEReference | Reference)* '\"' | \"'\" ([^%&'] | PEReference | Reference)* \"'\"\n" +
-                       "An entity value is required to contain legal XML characters."),
-    // P51_UNTERMINATED = 49
-        new Constraint("3.2.2", "[51]", "3.2.2 [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')'",
-                       "[51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')'\n" +
-                       "A mixed content model with child element types must be terminated by \")*\"."),
-    // P69_NAME_REQUIRED = 50
-        new Constraint("4.1", "[69]", "4.1 [69] PEReference ::= '%' Name ';'",
-                       "[69] PEReference ::= '%' Name ';'\n" +
-                       "The '&' delimiter must be followed by a valid Name in a parameter entity reference."),
-    // P69_SEMICOLON_REQUIRED = 51
-        new Constraint("4.1", "[69]", "4.1 [69] PEReference ::= '%' Name ';'",
-                       "[69] PEReference ::= '%' Name ';'\n" +
-                       "A parameter entity reference must end with a ';' delimiter."),
-    // P75_INVALID = 52
-        new Constraint("4.2.2", "[75]", "4.2.2 [75] ExternalID ::= 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral",
-                       "[75] ExternalID ::= 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral\n" +
-                       "An external entity declaration must begin with either \"SYSTEM\" or \"PUBLIC\"."),
-    // WFC_PES_IN_INTERNAL_SUBSET = 53
-        new Constraint("2.8", "[40] [44]", "2.8 WFC: PEs in Internal Subset",
-                       "Well-Formedness Constraint: PEs in Internal Subset\n" +
-                       "[28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' (markupdecl | PEReference | S)* ']' S?)? '>'\n" +
-                       "In the internal DTD subset, parameter-entity references can occur only where\n" +
-                       "markup declarations can occur, not within markup declarations."),
-    // P22_INVALID_CHARACTER = 54
-        new Constraint("2.8", "[22]", "2.8 [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?",
-                       "[22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?\n" +
-                       "The prolog is required to contain legal XML characters."),
-    // P27_INVALID_CHARACTER = 55
-        new Constraint("2.8", "[27]", "2.8 [27] Misc ::= Comment | PI |  S",
-                       "[27] Misc ::= Comment | PI |  S\n" +
-                       "The markup after the end of the element content is required to contain legal XML characters."),
-    // P20_INVALID_CHARACTER = 56
-        new Constraint("2.7", "[20]", "2.7 [20] CData ::= (Char* - (Char* ']]>' Char*))",
-                       "[20] CData ::= (Char* - (Char* ']]>' Char*))\n" +
-                       "CDATA sections are required to contain legal XML characters."),
-    // P43_INVALID_CHARACTER = 57
-        new Constraint("3.1", "[43]", "3.1 [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*",
-                       "[43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*\n" +
-                       "The content of elements is required to contain legal XML characters."),
-    // P39_UNTERMINATED = 58
-        new Constraint("3", "[39]", "3 [39] element ::= EmptyElemTag | STag content ETag",
-                       "[39] element ::= EmptyElemTag | STag content ETag\n" +
-                       "The end of every element that begins with a start-tag must be marked by an\n" +
-                       "end-tag containing a name that echoes the element's type as given in the\n" +
-                       "start-tag."),
-    // P42_UNTERMINATED = 59
-        new Constraint("3.1", "[42]", "3.1 [42] ETag ::= '</' Name S? '>'",
-                       "[42] ETag ::= '</' Name S? '>'\n" +
-                       "An end-tag must be terminated by a '>' delimiter."),
-    // P81_NOT_SUPPORTED = 60
-        new Constraint("4.3.3", "[81]", "4.3.3 [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*",
-                       "[81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*\n" +
-                       "It is a fatal error when an XML processor encounters an entity with an\n" +
-                       "encoding that it is unable to process.\n"),
-    // WFC_ENTITY_DECLARED = 61
-        new Constraint("4.1", "[68]", "4.1 WFC: Entity Declared",
-                       "Well-Formedness Constraint: Entity Declared\n" +
-                       "[68] EntityRef ::= '&' Name ';'\n" +
-                       "In a document without any DTD, a document with only an internal DTD subset\n" +
-                       "which contains no parameter entity references, or a document with\n" +
-                       "\"standalone='yes'\", the Name given in the entity reference must match that\n" +
-                       "in an entity declaration, except that well-formed documents need not declare\n" +
-                       "any of the following entities: amp, lt, gt, apos, quot. The declaration of a\n" +
-                       "parameter entity must precede any reference to it. Similarly, the\n" +
-                       "declaration of a general entity must precede any reference to it which\n" +
-                       "appears in a default value in an attribute-list declaration. Note that if\n" +
-                       "entities are declared in the external subset or in external parameter\n" +
-                       "entities, a non-validating processor is not obligated to read and process\n" +
-                       "their declarations; for such documents, the rule that an entity must be\n" +
-                       "declared is a well-formedness constraint only if standalone='yes'."),
-    // VC_ENTITY_DECLARED = 62
-        new Constraint("4.1", "[68]", "4.1 VC: Entity Declared",
-                       "Validity Constraint: Entity Declared\n" +
-                       "[68] EntityRef ::= '&' Name ';'\n" +
-                       "In a document with an external subset or external parameter entities with\n" +
-                       "\"standalone='no'\", the Name given in the entity reference must match that in\n" +
-                       "an entity declaration. For interoperability, valid documents should declare\n" +
-                       "the entities amp, lt, gt, apos, quot, in the form specified in\n" +
-                       "\"4.6 Predefined Entities\". The declaration of a parameter entity must\n" +
-                       "precede any reference to it. Similarly, the declaration of a general entity\n" +
-                       "must precede any reference to it which appears in a default value in an\n" +
-                       "attribute-list declaration."),
-    // WFC_PARSED_ENTITY = 63
-        new Constraint("4.1", "[68]", "4.1 WFC: Parsed Entity",
-                       "Well-Formedness Constraint: Parsed Entity\n" +
-                       "[68] EntityRef ::= '&' Name ';'\n" +
-                       "An entity reference must not contain the name of an unparsed entity.\n" +
-                       "Unparsed entities may be referred to only in attribute values declared to be\n" +
-                       "of type ENTITY or ENTITIES."),
-    // WFC_NO_EXTERNAL_ENTITY_REFERENCES = 64
-        new Constraint("3.1 2.3", "[41] [10]", "4.1 WFC: No External Entity References",
-                       "Well-Formedness Constraint: No External Entity References\n" +
-                       "[41] Attribute ::= Name Eq AttValue\n" +
-                       "[10] AttValue ::= '\"' ([^<&\"] | Reference)* '\"' | \"'\" ([^<&'] | Reference)* \"'\"\n" +
-                       "[68] EntityRef ::= '&' Name ';'\n" +
-                       "Attribute values cannot contain direct or indirect entity references to\n" +
-                       "external entities."),
-    // P33_INVALID = 65
-        new Constraint("2.12", "[33]", "2.12 [33] LanguageID ::= Langcode ('-' Subcode)*",
-                       "[33] LanguageID ::= Langcode ('-' Subcode)*\n" +
-                       "[34] Langcode ::= ISO639Code |  IanaCode |  UserCode\n" +
-                       "[35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])\n" +
-                       "[36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+\n" +
-                       "[37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+\n" +
-                       "[38] Subcode ::= ([a-z] | [A-Z])+\n" +
-                       "An xml:lang attribute value must match the LanguageID production."),
-    // P18_UNTERMINATED = 66
-        new Constraint("2.7", "[18]", "2.7 [18] CDSect ::= CDStart CData CDEnd",
-                       "[18] CDSect ::= CDStart CData CDEnd\n" +
-                       "[19] CDStart ::= '<![CDATA['\n" +
-                       "[20] CData ::= (Char* - (Char* ']]>' Char*))\n" +
-                       "[21] CDEnd ::= ']]>'\n" +
-                       "CDATA sections must be terminated by \"]]>\"."),
-    // VC_NO_DUPLICATE_TYPES = 67
-        new Constraint("3.2.2", "[51]", "3.2.2 VC: No Duplicate Types",
-                       "Validity Constraint: No Duplicate Types\n" +
-                       "[51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')'\n" +
-                       "The same name must not appear more than once in a single mixed-content\n" +
-                       "declaration."),
-    // P78_NOT_WELLFORMED = 68
-        new Constraint("4.3.2", "[78]", "4.3.2 [78] extParsedEnt ::= TextDecl? content",
-                       "[78] extParsedEnt ::= TextDecl? content\n" +
-                       "An internal general parsed entity is well-formed if its replacement text\n" +
-                       "matches the production labeled content.\n\n" +
-                       "A consequence of well-formedness in entities is that the logical and\n" +
-                       "physical structures in an XML document are properly nested; no start-tag,\n" +
-                       "end-tag, empty-element tag, element, comment, processing instruction,\n" +
-                       "character reference, or entity reference can begin in one entity and end in\n" +
-                       "another."),
-    // VC_ID_ATTRIBUTE_DEFAULT = 69
-        new Constraint("3.3.1 3.3", "[54] [53]", "3.3.1 VC: ID Attribute Default",
-                       "Validity Constraint: ID Attribute Default\n" +
-                       "[53] AttDef ::= S Name S AttType S DefaultDecl\n" +
-                       "[54] AttType ::= StringType | TokenizedType | EnumeratedType\n" +
-                       "[60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)\n" +
-                       "An ID attribute must have a declared default of #IMPLIED or #REQUIRED."),
-    // P53_NAME_REQUIRED = 70
-        new Constraint("3.3", "[53]", "3.3 [53] AttDef ::= S Name S AttType S DefaultDecl",
-                       "[52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'\n" +
-                       "[53] AttDef ::= S Name S AttType S DefaultDecl\n" +
-                       "In an attribute-list declaration, the Name in the AttDef rule is the name\n" +
-                       "of the attribute."),
-    // P53_ATTTYPE_REQUIRED = 71
-        new Constraint("3.3", "[53]", "3.3 [53] AttDef ::= S Name S AttType S DefaultDecl",
-                       "[52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'\n" +
-                       "[53] AttDef ::= S Name S AttType S DefaultDecl\n" +
-                       "."),
-    // P81_REQUIRED = 72
-        new Constraint("4.3.3", "[81]", "4.3.3 [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*",
-                       "[81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*\n" +
-                       "Parsed entities which are stored in an encoding other than UTF-8 or\n" +
-                       "UTF-16 must begin with an XML declaration or a text declaration that\n" +
-                       "contains an encoding declaration."),
-    // WFC_NO_RECURSION = 73
-        new Constraint("4.1", "[68]", "4.1 WFC: No Recursion",
-                       "Well-Formedness Constraint: No Recursion\n" +
-                       "[68] EntityRef ::= '&' Name ';'\n" +
-                       "[69] PEReference ::= '%' Name ';'\n" +
-                       "A parsed entity must not contain a recursive reference to itself, either\n" +
-                       "directly or indirectly."),
-    // VC_PROPER_DECLARATION_PE_NESTING = 74
-        new Constraint("2.8", "[29]", "2.8 VC: Proper Declaration/PE Nesting",
-                       "Validity Constraint: Proper Declaration/PE Nesting\n" +
-                       "[29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment\n" +
-                       "Parameter-entity replacement text must be properly nested with markup\n" +
-                       "declarations. That is to say, if either the first character or the last\n" +
-                       "character of a markup declaration (markupdecl above) is contained in the\n" +
-                       "replacement text for a parameter-entity reference, both must be contained in\n" +
-                       "the same replacement text."),
-    // VC_PROPER_GROUP_PE_NESTING = 75
-        new Constraint("3.2.1", "[47]", "3.2.1 VC: Proper Group/PE Nesting",
-                       "Validity Constraint: Proper Group/PE Nesting\n" +
-                       "[47] children ::= (choice | seq) ('?' | '*' | '+')?\n" +
-                       "[48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?\n" +
-                       "[49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'\n" +
-                       "[50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'\n" +
-                       "[51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')'\n" +
-                       "Parameter-entity replacement text must be properly nested with parenthetized\n" +
-                       "groups. That is to say, if either of the opening or closing parentheses in a\n" +
-                       "choice, seq, or Mixed construct is contained in the replacement text for a\n" +
-                       "parameter entity, both must be contained in the same replacement text."),
-    // VC_ID = 76
-        new Constraint("3.3.1", "[56]", "3.3.1 VC: ID",
-                       "Validity Constraint: ID\n" +
-                       "[56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'\n" +
-                       "Values of type ID must match the Name production. A name must not appear\n" +
-                       "more than once in an XML document as a value of this type; i.e., ID values\n" +
-                       "must uniquely identify the elements which bear them."),
-    // VC_ENTITY_NAME = 77
-        new Constraint("3.3.1", "[56]", "3.3.1 VC: Entity Name",
-                       "Validity Constraint: Entity Name\n" +
-                       "[56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'\n" +
-                       "Values of type ENTITY must match the Name production, values of type\n" +
-                       "ENTITIES must match Names; each Name must match the name of an unparsed\n" +
-                       "entity declared in the DTD."),
-    // VC_ATTRIBUTE_VALUE_TYPE = 78
-        new Constraint("3.1", "[41]", "3.1 VC: Attribute Value Type",
-                       "Validity Constraint: Attribute Value Type\n" +
-                       "[41] Attribute ::= Name Eq AttValue\n" +
-                       "The attribute must have been declared; the value must be of the type\n" +
-                       "declared for it."),
-    // VC_ELEMENT_VALID = 79
-        new Constraint("3", "[39]", "3 VC: Element Valid",
-                       "Validity Constraint: Element Valid\n" +
-                       "[39] element ::= EmptyElemTag | STag content ETag\n" +
-                       "An element is valid if there is a declaration matching elementdecl where the\n" +
-                       "Name matches the element type, and one of the following holds:\n\n" +
-                       "  1. The declaration matches EMPTY and the element has no content.\n" +
-                       "  2. The declaration matches children and the sequence of child elements\n" +
-                       "     belongs to the language generated by the regular expression in the\n" +
-                       "     content model, with optional white space (characters matching the\n" +
-                       "     nonterminal S) between each pair of child elements.\n" +
-                       "  3. The declaration matches Mixed and the content consists of character\n" +
-                       "     data and child elements whose types match names in the content model.\n" +
-                       "  4. The declaration matches ANY, and the types of any child elements have\n" +
-                       "     been declared."),
-    // VC_STANDALONE_DOCUMENT_DECLARATION = 80
-        new Constraint("2.9", "[32]", "2.9 VC: Standalone Document Declaration",
-                       "Validity Constraint: Standalone Document Declaration\n" +
-                       "[32] SDDecl ::= S 'standalone' Eq ((\"'\" ('yes' | 'no') \"'\") | ('\"' ('yes' | 'no') '\"'))\n" +
-                       "The standalone document declaration must have the value \"no\" if any external\n" +
-                       "markup declarations contain declarations of:\n\n" +
-                       "   * attributes with default values, if elements to which these attributes\n" +
-                       "     apply appear in the document without specifications of values for these\n" +
-                       "     attributes, or\n" +
-                       "   * entities (other than amp, lt, gt, apos, quot), if references to those\n" +
-                       "     entities appear in the document, or\n" +
-                       "   * attributes with values subject to normalization, where the attribute\n" +
-                       "     appears in the document with a value which will change as a result of\n" +
-                       "     normalization, or\n" +
-                       "   * element types with element content, if white space occurs directly\n" +
-                       "     within any instance of those types."),
-    // VC_ONE_ID_PER_ELEMENT_TYPE = 81
-        new Constraint("3.3.1", "[56]", "3.3.1 VC: One ID per Element Type",
-                       "Validity Constraint: One ID per Element Type\n" +
-                       "[56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'\n" +
-                       "No element type may have more than one ID attribute specified."),
-    // VC_UNIQUE_ELEMENT_TYPE_DECLARATION = 82
-        new Constraint("3.2", "[45]", "3.2 VC: Unique Element Type Declaration",
-                       "Validity Constraint: Unique Element Type Declaration\n" +
-                       "[45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'\n" +
-                       "No element type may be declared more than once."),
-    // P45_UNDECLARED_ELEMENT_IN_CONTENTSPEC = 83
-        new Constraint("3.2", "[45]", "3.2 [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'",
-                       "[45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'\n" +
-                       "At user option, an XML processor may issue a warning when a declaration\n" +
-                       "mentions an element type for which no declaration is provided, but this\n" +
-                       "is not an error."),
-
-    // VC_NOTATION_ATTRIBUTES = 84
-        new Constraint("?.?", "[??]", "", ""),
-    // P53_DUPLICATE = 85
-        new Constraint("?.?", "[??]", "", ""),
-    // VC_ENUMERATION = 86
-        new Constraint("?.?", "[??]", "", ""),
-    // VC_FIXED_ATTRIBUTE_DEFAULT = 87
-        new Constraint("?.?", "[??]", "", ""),
-    // VC_REQUIRED_ATTRIBUTE = 88
-        new Constraint("?.?", "[??]", "", ""),
-    // VC_NOTATION_DECLARED = 89
-        new Constraint("?.?", "[??]", "", ""),
-    // P58_NAME_REQUIRED = 90
-        new Constraint("?.?", "[??]", "", ""),
-    // P58_UNTERMINATED = 91
-        new Constraint("?.?", "[??]", "", ""),
-    // P59_NMTOKEN_REQUIRED = 92
-        new Constraint("?.?", "[??]", "", ""),
-    // P59_UNTERMINATED = 93
-        new Constraint("?.?", "[??]", "", ""),
-    // P70_SPACE = 94
-        new Constraint("?.?", "[??]", "", ""),
-    // P70_REQUIRED_NAME = 95
-        new Constraint("?.?", "[??]", "", ""),
-    // P70_REQUIRED_SPACE = 96
-        new Constraint("?.?", "[??]", "", ""),
-    // P71_UNTERMINATED = 97
-        new Constraint("?.?", "[??]", "", ""),
-    // P72_SPACE = 98
-        new Constraint("?.?", "[??]", "", ""),
-    // P72_UNTERMINATED = 99
-        new Constraint("?.?", "[??]", "", ""),
-    // P76_REQUIRED = 100
-        new Constraint("?.?", "[??]", "", ""),
-    // P82_NAME_REQUIRED = 101
-        new Constraint("?.?", "[??]", "", ""),
-    // P82_SPACE_REQUIRED = 102
-        new Constraint("?.?", "[??]", "", ""),
-    // P82_UNTERMINATED = 103
-        new Constraint("?.?", "[??]", "", ""),
-    // P14_INVALID = 104
-        new Constraint("?.?", "[??]", "", ""),
-    // P16_PITARGET_REQUIRED = 105
-        new Constraint("?.?", "[??]", "", ""),
-    // P16_REQUIRED = 106
-        new Constraint("?.?", "[??]", "", ""),
-    // P1_ELEMENT_REQUIRED = 107
-        new Constraint("?.?", "[??]", "", ""),
-    // P22_NOT_RECOGNIZED = 108
-        new Constraint("?.?", "[??]", "", ""),
-    // P27_NOT_RECOGNIZED = 109
-        new Constraint("?.?", "[??]", "", ""),
-    // P43_NOT_RECOGNIZED = 110
-        new Constraint("?.?", "[??]", "", ""),
-    // P52_ELEMENT_TYPE_REQUIRED = 111
-        new Constraint("?.?", "[??]", "", ""),
-    // P52_SPACE_REQUIRED = 112
-        new Constraint("?.?", "[??]", "", ""),
-    // P53_SPACE_REQUIRED = 113
-        new Constraint("?.?", "[??]", "", ""),
-    // P58_OPEN_PAREN_REQUIRED = 114
-        new Constraint("?.?", "[??]", "", ""),
-    // P58_SPACE_REQUIRED = 115
-        new Constraint("?.?", "[??]", "", ""),
-    // P60_SPACE_REQUIRED = 116
-        new Constraint("?.?", "[??]", "", ""),
-    // S2_10_DECLARATION_ILLEGAL = 117
-        new Constraint("?.?", "[??]", "", ""),
-    // P39_ELEMENT_TYPE_REQUIRED = 118
-        new Constraint("?.?", "[??]", "", ""),
-    // P28_ROOT_ELEMENT_TYPE_REQUIRED = 119
-        new Constraint("?.?", "[??]", "", ""),
-    // P28_SPACE_REQUIRED = 120
-        new Constraint("?.?", "[??]", "", ""),
-    // P28_UNTERMINATED = 121
-        new Constraint("?.?", "[??]", "", ""),
-    // P29_NOT_RECOGNIZED = 122
-        new Constraint("?.?", "[??]", "", ""),
-    // P45_CONTENTSPEC_REQUIRED = 123
-        new Constraint("?.?", "[??]", "", ""),
-    // P45_ELEMENT_TYPE_REQUIRED = 124
-        new Constraint("?.?", "[??]", "", ""),
-    // P45_SPACE_REQUIRED = 125
-        new Constraint("?.?", "[??]", "", ""),
-    // P45_UNTERMINATED = 126
-        new Constraint("?.?", "[??]", "", ""),
-    // P47_CLOSE_PAREN_REQUIRED = 127
-        new Constraint("?.?", "[??]", "", ""),
-    // P47_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED = 128
-        new Constraint("?.?", "[??]", "", ""),
-    // P51_CLOSE_PAREN_REQUIRED = 129
-        new Constraint("?.?", "[??]", "", ""),
-    // P51_ELEMENT_TYPE_REQUIRED = 130
-        new Constraint("?.?", "[??]", "", ""),
-    // P75_SPACE_REQUIRED = 131
-        new Constraint("?.?", "[??]", "", ""),
-    // P76_SPACE_REQUIRED = 132
-        new Constraint("?.?", "[??]", "", ""),
-    // P15_UNTERMINATED = 133
-        new Constraint("?.?", "[??]", "", ""),
-    // P16_UNTERMINATED = 134
-        new Constraint("?.?", "[??]", "", ""),
-    // P67_UNTERMINATED = 135
-        new Constraint("?.?", "[??]", "", ""),
-    // P10_UNTERMINATED = 136
-        new Constraint("?.?", "[??]", "", ""),
-    // P22_XMLDECL_MUST_BE_FIRST = 137
-        new Constraint("?.?", "[??]", "", ""),
-    // P30_TEXTDECL_MUST_BE_FIRST = 138
-        new Constraint("?.?", "[??]", "", ""),
-    // P5_INVALID_CHARACTER = 139
-        new Constraint("?.?", "[??]", "", ""),
-    // P11_UNTERMINATED = 140
-        new Constraint("?.?", "[??]", "", ""),
-    // P12_UNTERMINATED = 141
-        new Constraint("?.?", "[??]", "", ""),
-    // P11_URI_FRAGMENT = 142
-        new Constraint("?.?", "[??]", "", ""),
-    // VC_ONE_NOTATION_PER_ELEMENT_TYPE = 143
-        new Constraint("3.3.1", "[58]", "VC: One Notation per Element Type",
-                       "Validity Constraint: One Notation per Element Type\n" +
-                       "[58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'\n" +
-                       "No element type may have more than one NOTATION attribute specified."),
-    // NC_PREFIX_DECLARED = 144
-        new Constraint("4.", "", "NC: Prefix Declared", ""),
-
-        // ...
-        new Constraint(null, null, null, null)
-    };
- */
-}
-
-/*
-class Constraint {
-    String sections;
-    String productions;
-    String shortDesc;
-    String longDesc;
-    Constraint(String sections, String productions, String shortDesc, String longDesc) {
-        this.sections = sections;
-        this.productions = productions;
-        this.shortDesc = shortDesc;
-        this.longDesc = longDesc;
-    }
-}
- */
diff --git a/src/org/apache/xerces/utils/regex/BMPattern.java b/src/org/apache/xerces/utils/regex/BMPattern.java
deleted file mode 100644
index 8587f94..0000000
--- a/src/org/apache/xerces/utils/regex/BMPattern.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils.regex;
-
-import java.text.CharacterIterator;
-
-/**
- * Boyer-Moore searcher.
- */
-public class BMPattern {
-    char[] pattern;
-    int[] shiftTable;
-    boolean ignoreCase;
-
-    public BMPattern(String pat, boolean ignoreCase) {
-        this(pat, 256, ignoreCase);
-    }
-
-    public BMPattern(String pat, int tableSize, boolean ignoreCase) {
-        this.pattern = pat.toCharArray();
-        this.shiftTable = new int[tableSize];
-        this.ignoreCase = ignoreCase;
-
-        int length = pattern.length;
-        for (int i = 0;  i < this.shiftTable.length;  i ++)
-            this.shiftTable[i] = length;
-
-        for (int i = 0;  i < length;  i ++) {
-            char ch = this.pattern[i];
-            int diff = length-i-1;
-            int index = ch % this.shiftTable.length;
-            if (diff < this.shiftTable[index])
-                this.shiftTable[index] = diff;
-            if (this.ignoreCase) {
-                ch = Character.toUpperCase(ch);
-                index = ch % this.shiftTable.length;
-                if (diff < this.shiftTable[index])
-                    this.shiftTable[index] = diff;
-                ch = Character.toLowerCase(ch);
-                index = ch % this.shiftTable.length;
-                if (diff < this.shiftTable[index])
-                    this.shiftTable[index] = diff;
-            }
-        }
-    }
-
-    /**
-     *
-     * @return -1 if <var>iterator</var> does not contain this pattern.
-     */
-    public int matches(CharacterIterator iterator, int start, int limit) {
-        if (this.ignoreCase)  return this.matchesIgnoreCase(iterator, start, limit);
-        int plength = this.pattern.length;
-        if (plength == 0)  return start;
-        int index = start+plength;
-        while (index <= limit) {
-            int pindex = plength;
-            int nindex = index+1;
-            char ch;
-            do {
-                if ((ch = iterator.setIndex(--index)) != this.pattern[--pindex])
-                    break;
-                if (pindex == 0)
-                    return index;
-            } while (pindex > 0);
-            index += this.shiftTable[ch % this.shiftTable.length]+1;
-            if (index < nindex)  index = nindex;
-        }
-        return -1;
-    }
-
-    /**
-     *
-     * @return -1 if <var>str</var> does not contain this pattern.
-     */
-    public int matches(String str, int start, int limit) {
-        if (this.ignoreCase)  return this.matchesIgnoreCase(str, start, limit);
-        int plength = this.pattern.length;
-        if (plength == 0)  return start;
-        int index = start+plength;
-        while (index <= limit) {
-            //System.err.println("Starts at "+index);
-            int pindex = plength;
-            int nindex = index+1;
-            char ch;
-            do {
-                if ((ch = str.charAt(--index)) != this.pattern[--pindex])
-                    break;
-                if (pindex == 0)
-                    return index;
-            } while (pindex > 0);
-            index += this.shiftTable[ch % this.shiftTable.length]+1;
-            if (index < nindex)  index = nindex;
-        }
-        return -1;
-    }
-    /**
-     *
-     * @return -1 if <var>chars</char> does not contain this pattern.
-     */
-    public int matches(char[] chars, int start, int limit) {
-        if (this.ignoreCase)  return this.matchesIgnoreCase(chars, start, limit);
-        int plength = this.pattern.length;
-        if (plength == 0)  return start;
-        int index = start+plength;
-        while (index <= limit) {
-            //System.err.println("Starts at "+index);
-            int pindex = plength;
-            int nindex = index+1;
-            char ch;
-            do {
-                if ((ch = chars[--index]) != this.pattern[--pindex])
-                    break;
-                if (pindex == 0)
-                    return index;
-            } while (pindex > 0);
-            index += this.shiftTable[ch % this.shiftTable.length]+1;
-            if (index < nindex)  index = nindex;
-        }
-        return -1;
-    }
-
-    int matchesIgnoreCase(CharacterIterator iterator, int start, int limit) {
-        int plength = this.pattern.length;
-        if (plength == 0)  return start;
-        int index = start+plength;
-        while (index <= limit) {
-            int pindex = plength;
-            int nindex = index+1;
-            char ch;
-            do {
-                char ch1 = ch = iterator.setIndex(--index);
-                char ch2 = this.pattern[--pindex];
-                if (ch1 != ch2) {
-                    ch1 = Character.toUpperCase(ch1);
-                    ch2 = Character.toUpperCase(ch2);
-                    if (ch1 != ch2 && Character.toLowerCase(ch1) != Character.toLowerCase(ch2))
-                        break;
-                }
-                if (pindex == 0)
-                    return index;
-            } while (pindex > 0);
-            index += this.shiftTable[ch % this.shiftTable.length]+1;
-            if (index < nindex)  index = nindex;
-        }
-        return -1;
-    }
-    
-    int matchesIgnoreCase(String text, int start, int limit) {
-        int plength = this.pattern.length;
-        if (plength == 0)  return start;
-        int index = start+plength;
-        while (index <= limit) {
-            int pindex = plength;
-            int nindex = index+1;
-            char ch;
-            do {
-                char ch1 = ch = text.charAt(--index);
-                char ch2 = this.pattern[--pindex];
-                if (ch1 != ch2) {
-                    ch1 = Character.toUpperCase(ch1);
-                    ch2 = Character.toUpperCase(ch2);
-                    if (ch1 != ch2 && Character.toLowerCase(ch1) != Character.toLowerCase(ch2))
-                        break;
-                }
-                if (pindex == 0)
-                    return index;
-            } while (pindex > 0);
-            index += this.shiftTable[ch % this.shiftTable.length]+1;
-            if (index < nindex)  index = nindex;
-        }
-        return -1;
-    }
-    int matchesIgnoreCase(char[] chars, int start, int limit) {
-        int plength = this.pattern.length;
-        if (plength == 0)  return start;
-        int index = start+plength;
-        while (index <= limit) {
-            int pindex = plength;
-            int nindex = index+1;
-            char ch;
-            do {
-                char ch1 = ch = chars[--index];
-                char ch2 = this.pattern[--pindex];
-                if (ch1 != ch2) {
-                    ch1 = Character.toUpperCase(ch1);
-                    ch2 = Character.toUpperCase(ch2);
-                    if (ch1 != ch2 && Character.toLowerCase(ch1) != Character.toLowerCase(ch2))
-                        break;
-                }
-                if (pindex == 0)
-                    return index;
-            } while (pindex > 0);
-            index += this.shiftTable[ch % this.shiftTable.length]+1;
-            if (index < nindex)  index = nindex;
-        }
-        return -1;
-    }
-
-    /*
-    public static void main(String[] argv) {
-        try {
-            int[] shiftTable = new int[256];
-            initializeBoyerMoore(argv[0], shiftTable, true);
-            int o = -1;
-            CharacterIterator ite = new java.text.StringCharacterIterator(argv[1]);
-            long start = System.currentTimeMillis();
-            //for (int i = 0;  i < 10000;  i ++)
-                o = searchIgnoreCasesWithBoyerMoore(ite, 0, argv[0], shiftTable);
-            start = System.currentTimeMillis()-start;
-            System.out.println("Result: "+o+", Elapsed: "+start);
-        } catch (Exception ex) {
-            ex.printStackTrace();
-        }
-    }*/
-}
-
diff --git a/src/org/apache/xerces/utils/regex/Makefile b/src/org/apache/xerces/utils/regex/Makefile
deleted file mode 100644
index 16567cf..0000000
--- a/src/org/apache/xerces/utils/regex/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-TARGETS=\
-	BMPattern.class \
-	Match.class \
-	Op.class \
-	ParseException.class \
-	ParserForXMLSchema.class \
-	REUtil.class \
-	RangeToken.class \
-	RegexParser.class \
-	RegularExpression.class \
-	Token.class 
-
-
-DIRS =
-
-TOP = ../../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xerces/utils/regex/Match.java b/src/org/apache/xerces/utils/regex/Match.java
deleted file mode 100644
index 83f293b..0000000
--- a/src/org/apache/xerces/utils/regex/Match.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils.regex;
-
-
-import java.text.CharacterIterator;
-
-/**
- * 
- * An instance of this class has ranges captured in matching.
- *
- * @see org.apache.xerces.utils.regex.RegularExpression#matches(char[], int, int, org.apache.xerces.utils.regex.Match)
- * @see org.apache.xerces.utils.regex.RegularExpression#matches(char[], org.apache.xerces.utils.regex.Match)
- * @see org.apache.xerces.utils.regex.RegularExpression#matches(java.text.CharacterIterator, org.apache.xerces.utils.regex.Match)
- * @see org.apache.xerces.utils.regex.RegularExpression#matches(java.lang.String, int, int, org.apache.xerces.utils.regex.Match)
- * @see org.apache.xerces.utils.regex.RegularExpression#matches(java.lang.String, org.apache.xerces.utils.regex.Match)
- * @author TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;
- */
-public class Match implements Cloneable {
-    int[] beginpos = null;
-    int[] endpos = null;
-    int nofgroups = 0;
-
-    CharacterIterator ciSource = null;
-    String strSource = null;
-    char[] charSource = null;
-
-    /**
-     * Creates an instance.
-     */
-    public Match() {
-    }
-
-    /**
-     *
-     */
-    public synchronized Object clone() {
-        Match ma = new Match();
-        if (this.nofgroups > 0) {
-            ma.setNumberOfGroups(this.nofgroups);
-            if (this.ciSource != null)  ma.setSource(this.ciSource);
-            if (this.strSource != null)  ma.setSource(this.strSource);
-            for (int i = 0;  i < this.nofgroups;  i ++) {
-                ma.setBeginning(i, this.getBeginning(i));
-                ma.setEnd(i, this.getEnd(i));
-            }
-        }
-        return ma;
-    }
-
-    /**
-     *
-     */
-    protected void setNumberOfGroups(int n) {
-        int oldn = this.nofgroups;
-        this.nofgroups = n;
-        if (oldn <= 0
-            || oldn < n || n*2 < oldn) {
-            this.beginpos = new int[n];
-            this.endpos = new int[n];
-        }
-        for (int i = 0;  i < n;  i ++) {
-            this.beginpos[i] = -1;
-            this.endpos[i] = -1;
-        }
-    }
-
-    /**
-     *
-     */
-    protected void setSource(CharacterIterator ci) {
-        this.ciSource = ci;
-        this.strSource = null;
-        this.charSource = null;
-    }
-    /**
-     *
-     */
-    protected void setSource(String str) {
-        this.ciSource = null;
-        this.strSource = str;
-        this.charSource = null;
-    }
-    /**
-     *
-     */
-    protected void setSource(char[] chars) {
-        this.ciSource = null;
-        this.strSource = null;
-        this.charSource = chars;
-    }
-
-    /**
-     *
-     */
-    protected void setBeginning(int index, int v) {
-        this.beginpos[index] = v;
-    }
-
-    /**
-     *
-     */
-    protected void setEnd(int index, int v) {
-        this.endpos[index] = v;
-    }
-
-    /**
-     * Return the number of regular expression groups.
-     * This method returns 1 when the regular expression has no capturing-parenthesis.
-     */
-    public int getNumberOfGroups() {
-        if (this.nofgroups <= 0)
-            throw new IllegalStateException("A result is not set.");
-        return this.nofgroups;
-    }
-
-    /**
-     * Return a start position in the target text matched to specified regular expression group.
-     *
-     * @param index Less than <code>getNumberOfGroups()</code>.
-     */
-    public int getBeginning(int index) {
-        if (this.beginpos == null)
-            throw new IllegalStateException("A result is not set.");
-        if (index < 0 || this.nofgroups <= index)
-            throw new IllegalArgumentException("The parameter must be less than "
-                                               +this.nofgroups+": "+index);
-        return this.beginpos[index];
-    }
-
-    /**
-     * Return an end position in the target text matched to specified regular expression group.
-     *
-     * @param index Less than <code>getNumberOfGroups()</code>.
-     */
-    public int getEnd(int index) {
-        if (this.endpos == null)
-            throw new IllegalStateException("A result is not set.");
-        if (index < 0 || this.nofgroups <= index)
-            throw new IllegalArgumentException("The parameter must be less than "
-                                               +this.nofgroups+": "+index);
-        return this.endpos[index];
-    }
-
-    /**
-     * Return an substring of the target text matched to specified regular expression group.
-     *
-     * @param index Less than <code>getNumberOfGroups()</code>.
-     */
-    public String getCapturedText(int index) {
-        if (this.beginpos == null)
-            throw new IllegalStateException("match() has never been called.");
-        if (index < 0 || this.nofgroups <= index)
-            throw new IllegalArgumentException("The parameter must be less than "
-                                               +this.nofgroups+": "+index);
-        String ret;
-        int begin = this.beginpos[index], end = this.endpos[index];
-        if (begin < 0 || end < 0)  return null;
-        if (this.ciSource != null) {
-            ret = REUtil.substring(this.ciSource, begin, end);
-        } else if (this.strSource != null) {
-            ret = this.strSource.substring(begin, end);
-        } else {
-            ret = new String(this.charSource, begin, end-begin);
-        }
-        return ret;
-    }
-}
diff --git a/src/org/apache/xerces/utils/regex/Op.java b/src/org/apache/xerces/utils/regex/Op.java
deleted file mode 100644
index 55f07a1..0000000
--- a/src/org/apache/xerces/utils/regex/Op.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils.regex;
-
-
-import java.util.Vector;
-
-/**
- */
-class Op {
-    static final int DOT = 0;
-    static final int CHAR = 1;                  // Single character
-    static final int RANGE = 3;                 // [a-zA-Z]
-    static final int NRANGE = 4;                // [^a-zA-Z]
-    static final int ANCHOR = 5;                // ^ $ ...
-    static final int STRING = 6;                // literal String 
-    static final int CLOSURE = 7;               // X*
-    static final int NONGREEDYCLOSURE = 8;      // X*?
-    static final int QUESTION = 9;              // X?
-    static final int NONGREEDYQUESTION = 10;    // X??
-    static final int UNION = 11;                // X|Y
-    static final int CAPTURE = 15;              // ( and )
-    static final int BACKREFERENCE = 16;        // \1 \2 ...
-    static final int LOOKAHEAD = 20;            // (?=...)
-    static final int NEGATIVELOOKAHEAD = 21;    // (?!...)
-    static final int LOOKBEHIND = 22;           // (?<=...)
-    static final int NEGATIVELOOKBEHIND = 23;   // (?<!...)
-    static final int INDEPENDENT = 24;          // (?>...)
-    static final int MODIFIER = 25;             // (?ims-ims:...)
-    static final int CONDITION = 26;            // (?(..)yes|no)
-
-    static int nofinstances = 0;
-    static final boolean COUNT = false;
-
-    static Op createDot() {
-        if (Op.COUNT)  Op.nofinstances ++;
-        return new Op(Op.DOT);
-    }
-    static CharOp createChar(int data) {
-        if (Op.COUNT)  Op.nofinstances ++;
-        return new CharOp(Op.CHAR, data);
-    }
-    static CharOp createAnchor(int data) {
-        if (Op.COUNT)  Op.nofinstances ++;
-        return new CharOp(Op.ANCHOR, data);
-    }
-    static CharOp createCapture(int number, Op next) {
-        if (Op.COUNT)  Op.nofinstances ++;
-        CharOp op = new CharOp(Op.CAPTURE, number);
-        op.next = next;
-        return op;
-    }
-    static UnionOp createUnion(int size) {
-        if (Op.COUNT)  Op.nofinstances ++;
-        //System.err.println("Creates UnionOp");
-        return new UnionOp(Op.UNION, size);
-    }
-    static ChildOp createClosure(int id) {
-        if (Op.COUNT)  Op.nofinstances ++;
-        return new ModifierOp(Op.CLOSURE, id, -1);
-    }
-    static ChildOp createNonGreedyClosure() {
-        if (Op.COUNT)  Op.nofinstances ++;
-        return new ChildOp(Op.NONGREEDYCLOSURE);
-    }
-    static ChildOp createQuestion(boolean nongreedy) {
-        if (Op.COUNT)  Op.nofinstances ++;
-        return new ChildOp(nongreedy ? Op.NONGREEDYQUESTION : Op.QUESTION);
-    }
-    static RangeOp createRange(Token tok) {
-        if (Op.COUNT)  Op.nofinstances ++;
-        return new RangeOp(Op.RANGE, tok);
-    }
-    static ChildOp createLook(int type, Op next, Op branch) {
-        if (Op.COUNT)  Op.nofinstances ++;
-        ChildOp op = new ChildOp(type);
-        op.setChild(branch);
-        op.next = next;
-        return op;
-    }
-    static CharOp createBackReference(int refno) {
-        if (Op.COUNT)  Op.nofinstances ++;
-        return new CharOp(Op.BACKREFERENCE, refno);
-    }
-    static StringOp createString(String literal) {
-        if (Op.COUNT)  Op.nofinstances ++;
-        return new StringOp(Op.STRING, literal);
-    }
-    static ChildOp createIndependent(Op next, Op branch) {
-        if (Op.COUNT)  Op.nofinstances ++;
-        ChildOp op = new ChildOp(Op.INDEPENDENT);
-        op.setChild(branch);
-        op.next = next;
-        return op;
-    }
-    static ModifierOp createModifier(Op next, Op branch, int add, int mask) {
-        if (Op.COUNT)  Op.nofinstances ++;
-        ModifierOp op = new ModifierOp(Op.MODIFIER, add, mask);
-        op.setChild(branch);
-        op.next = next;
-        return op;
-    }
-    static ConditionOp createCondition(Op next, int ref, Op conditionflow, Op yesflow, Op noflow) {
-        if (Op.COUNT)  Op.nofinstances ++;
-        ConditionOp op = new ConditionOp(Op.CONDITION, ref, conditionflow, yesflow, noflow);
-        op.next = next;
-        return op;
-    }
-
-    int type;
-    Op next = null;
-
-    protected Op(int type) {
-        this.type = type;
-    }
-
-    int size() {                                // for UNION
-        return 0;
-    }
-    Op elementAt(int index) {                   // for UNIoN
-        throw new RuntimeException("Internal Error: type="+this.type);
-    }
-    Op getChild() {                             // for CLOSURE, QUESTION
-        throw new RuntimeException("Internal Error: type="+this.type);
-    }
-                                                // ModifierOp
-    int getData() {                             // CharOp  for CHAR, BACKREFERENCE, CAPTURE, ANCHOR, 
-        throw new RuntimeException("Internal Error: type="+this.type);
-    }
-    int getData2() {                            // ModifierOp
-        throw new RuntimeException("Internal Error: type="+this.type);
-    }
-    RangeToken getToken() {                     // RANGE, NRANGE
-        throw new RuntimeException("Internal Error: type="+this.type);
-    }
-    String getString() {                        // STRING
-        throw new RuntimeException("Internal Error: type="+this.type);
-    }
-
-    // ================================================================
-    static class CharOp extends Op {
-        int charData;
-        CharOp(int type, int data) {
-            super(type);
-            this.charData = data;
-        }
-        int getData() {
-            return this.charData;
-        }
-    }
-
-    // ================================================================
-    static class UnionOp extends Op {
-        Vector branches;
-        UnionOp(int type, int size) {
-            super(type);
-            this.branches = new Vector(size);
-        }
-        void addElement(Op op) {
-            this.branches.addElement(op);
-        }
-        int size() {
-            return this.branches.size();
-        }
-        Op elementAt(int index) {
-            return (Op)this.branches.elementAt(index);
-        }
-    }
-
-    // ================================================================
-    static class ChildOp extends Op {
-        Op child;
-        ChildOp(int type) {
-            super(type);
-        }
-        void setChild(Op child) {
-            this.child = child;
-        }
-        Op getChild() {
-            return this.child;
-        }
-    }
-    // ================================================================
-    static class ModifierOp extends ChildOp {
-        int v1;
-        int v2;
-        ModifierOp(int type, int v1, int v2) {
-            super(type);
-            this.v1 = v1;
-            this.v2 = v2;
-        }
-        int getData() {
-            return this.v1;
-        }
-        int getData2() {
-            return this.v2;
-        }
-    }
-    // ================================================================
-    static class RangeOp extends Op {
-        Token tok;
-        RangeOp(int type, Token tok) {
-            super(type);
-            this.tok = tok;
-        }
-        RangeToken getToken() {
-            return (RangeToken)this.tok;
-        }
-    }
-    // ================================================================
-    static class StringOp extends Op {
-        String string;
-        StringOp(int type, String literal) {
-            super(type);
-            this.string = literal;
-        }
-        String getString() {
-            return this.string;
-        }
-    }
-    // ================================================================
-    static class ConditionOp extends Op {
-        int refNumber;
-        Op condition;
-        Op yes;
-        Op no;
-        ConditionOp(int type, int refno, Op conditionflow, Op yesflow, Op noflow) {
-            super(type);
-            this.refNumber = refno;
-            this.condition = conditionflow;
-            this.yes = yesflow;
-            this.no = noflow;
-        }
-    }
-}
diff --git a/src/org/apache/xerces/utils/regex/ParseException.java b/src/org/apache/xerces/utils/regex/ParseException.java
deleted file mode 100644
index 0ae0139..0000000
--- a/src/org/apache/xerces/utils/regex/ParseException.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils.regex;
-
-
-
-/**
- *
- * @author TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;
- */
-public class ParseException extends RuntimeException {
-    int location;
-
-    /*
-    public ParseException(String mes) {
-        this(mes, -1);
-    }
-    */
-    /**
-     *
-     */
-    public ParseException(String mes, int location) {
-        super(mes);
-        this.location = location;
-    }
-
-    /**
-     *
-     * @return -1 if location information is not available.
-     */
-    public int getLocation() {
-        return this.location;
-    }
-}
diff --git a/src/org/apache/xerces/utils/regex/ParserForXMLSchema.java b/src/org/apache/xerces/utils/regex/ParserForXMLSchema.java
deleted file mode 100644
index 15d064d..0000000
--- a/src/org/apache/xerces/utils/regex/ParserForXMLSchema.java
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils.regex;
-
-
-
-import java.util.Hashtable;
-import java.util.Locale;
-
-/**
- * A regular expression parser for the XML Shema.
- *
- * @author TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;
- */
-class ParserForXMLSchema extends RegexParser {
-
-    public ParserForXMLSchema() {
-        //this.setLocale(Locale.getDefault());
-    }
-    public ParserForXMLSchema(Locale locale) {
-        //this.setLocale(locale);
-    }
-
-    Token processCaret() throws ParseException {
-        this.next();
-        return Token.createChar('^');
-    }
-    Token processDollar() throws ParseException {
-        this.next();
-        return Token.createChar('$');
-     }
-    Token processLookahead() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processNegativelookahead() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processLookbehind() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processNegativelookbehind() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processBacksolidus_A() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processBacksolidus_Z() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processBacksolidus_z() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processBacksolidus_b() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processBacksolidus_B() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processBacksolidus_lt() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processBacksolidus_gt() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processStar(Token tok) throws ParseException {
-        this.next();
-        return Token.createClosure(tok);
-    }
-    Token processPlus(Token tok) throws ParseException {
-        // X+ -> XX*
-        this.next();
-        return Token.createConcat(tok, Token.createClosure(tok));
-    }
-    Token processQuestion(Token tok) throws ParseException {
-        // X? -> X|
-        this.next();
-        Token par = Token.createUnion();
-        par.addChild(tok);
-        par.addChild(Token.createEmpty());
-        return par;
-    }
-    boolean checkQuestion(int off) {
-        return false;
-    }
-    Token processParen() throws ParseException {
-        this.next();
-        Token tok = Token.createParen(this.parseRegex(), 0);
-        if (this.read() != super.T_RPAREN)  throw ex("parser.factor.1", this.offset-1);
-        this.next();                            // Skips ')'
-        return tok;
-    }
-    Token processParen2() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processCondition() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processModifiers() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processIndependent() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processBacksolidus_c() throws ParseException {
-        this.next();
-        return this.getTokenForShorthand('c');
-    }
-    Token processBacksolidus_C() throws ParseException {
-        this.next();
-        return this.getTokenForShorthand('C');
-    }
-    Token processBacksolidus_i() throws ParseException {
-        this.next();
-        return this.getTokenForShorthand('i');
-    }
-    Token processBacksolidus_I() throws ParseException {
-        this.next();
-        return this.getTokenForShorthand('I');
-    }
-    Token processBacksolidus_g() throws ParseException {
-        throw this.ex("parser.process.1", this.offset-2);
-    }
-    Token processBacksolidus_X() throws ParseException {
-        throw ex("parser.process.1", this.offset-2);
-    }
-    Token processBackreference() throws ParseException {
-        throw ex("parser.process.1", this.offset-4);
-    }
-
-    int processCIinCharacterClass(RangeToken tok, int c) {
-        tok.mergeRanges(this.getTokenForShorthand(c));
-        return -1;
-    }
-
-
-    /**
-     * Parses a character-class-expression, not a character-class-escape.
-     *
-     * c-c-expression   ::= '[' c-group ']'
-     * c-group          ::= positive-c-group | negative-c-group | c-c-subtraction
-     * positive-c-group ::= (c-range | c-c-escape)+
-     * negative-c-group ::= '^' positive-c-group
-     * c-c-subtraction  ::= (positive-c-group | negative-c-group) subtraction
-     * subtraction      ::= '-' c-c-expression
-     * c-range          ::= single-range | from-to-range
-     * single-range     ::= multi-c-escape | category-c-escape | block-c-escape | <any XML char>
-     * cc-normal-c      ::= <any character except [, ], \>
-     * from-to-range    ::= cc-normal-c '-' cc-normal-c
-     *
-     * @param useNrage Ignored.
-     * @return This returns no NrageToken.
-     */
-    protected RangeToken parseCharacterClass(boolean useNrange) throws ParseException {
-        this.setContext(S_INBRACKETS);
-        this.next();                            // '['
-        boolean nrange = false;
-        RangeToken base = null;
-        RangeToken tok;
-        if (this.read() == T_CHAR && this.chardata == '^') {
-            nrange = true;
-            this.next();                        // '^'
-            base = Token.createRange();
-            base.addRange(0, Token.UTF16_MAX);
-            tok = Token.createRange();
-        } else {
-            tok = Token.createRange();
-        }
-        int type;
-        boolean firstloop = true;
-        while ((type = this.read()) != T_EOF) { // Don't use 'cotinue' for this loop.
-            // single-range | from-to-range | subtraction
-            if (type == T_CHAR && this.chardata == ']' && !firstloop) {
-                if (nrange) {
-                    base.subtractRanges(tok);
-                    tok = base;
-                }
-                break;
-            }
-            int c = this.chardata;
-            boolean end = false;
-            if (type == T_BACKSOLIDUS) {
-                switch (c) {
-                  case 'd':  case 'D':
-                  case 'w':  case 'W':
-                  case 's':  case 'S':
-                    tok.mergeRanges(this.getTokenForShorthand(c));
-                    end = true;
-                    break;
-
-                  case 'i':  case 'I':
-                  case 'c':  case 'C':
-                    c = this.processCIinCharacterClass(tok, c);
-                    if (c < 0)  end = true;
-                    break;
-                    
-                  case 'p':
-                  case 'P':
-                    int pstart = this.offset;
-                    RangeToken tok2 = this.processBacksolidus_pP(c);
-                    if (tok2 == null)  throw this.ex("parser.atom.5", pstart);
-                    tok.mergeRanges(tok2);
-                    end = true;
-                    break;
-
-                  default:
-                    c = this.decodeEscaped();
-                } // \ + c
-            } // backsolidus
-            else if (type == T_XMLSCHEMA_CC_SUBTRACTION && !firstloop) {
-                                                // Subraction
-                if (nrange) {
-                    base.subtractRanges(tok);
-                    tok = base;
-                }
-                RangeToken range2 = this.parseCharacterClass(false);
-                tok.subtractRanges(range2);
-                if (this.read() != T_CHAR || this.chardata != ']')
-                    throw this.ex("parser.cc.5", this.offset);
-                break;                          // Exit this loop
-            }
-            this.next();
-            if (!end) {                         // if not shorthands...
-                if (type == T_CHAR) {
-                    if (c == '[')  throw this.ex("parser.cc.6", this.offset-2);
-                    if (c == ']')  throw this.ex("parser.cc.7", this.offset-2);
-                }
-                if (this.read() != T_CHAR || this.chardata != '-') { // Here is no '-'.
-                    tok.addRange(c, c);
-                } else {                        // Found '-'
-                                                // Is this '-' is a from-to token??
-                    this.next(); // Skips '-'
-                    if ((type = this.read()) == T_EOF)  throw this.ex("parser.cc.2", this.offset);
-                                                // c '-' ']' -> '-' is a single-range.
-                    if (type == T_CHAR && this.chardata == ']') {
-                        tok.addRange(c, c);
-                        tok.addRange('-', '-');
-                    }
-                                                // c '-' '-[' -> '-' is a single-range.
-                    else if (type == T_XMLSCHEMA_CC_SUBTRACTION) {
-                        tok.addRange(c, c);
-                        tok.addRange('-', '-');
-                    } else {
-                        int rangeend = this.chardata;
-                        if (type == T_CHAR) {
-                            if (rangeend == '[')  throw this.ex("parser.cc.6", this.offset-1);
-                            if (rangeend == ']')  throw this.ex("parser.cc.7", this.offset-1);
-                        }
-                        if (type == T_BACKSOLIDUS)
-                            rangeend = this.decodeEscaped();
-                        this.next();
-                        tok.addRange(c, rangeend);
-                    }
-                }
-            }
-            firstloop = false;
-        }
-        if (this.read() == T_EOF)
-            throw this.ex("parser.cc.2", this.offset);
-        tok.sortRanges();
-        tok.compactRanges();
-        //tok.dumpRanges();
-        this.setContext(S_NORMAL);
-        this.next();                    // Skips ']'
-
-        return tok;
-    }
-
-    protected RangeToken parseSetOperations() throws ParseException {
-        throw this.ex("parser.process.1", this.offset);
-    }
- 
-    Token getTokenForShorthand(int ch) {
-        switch (ch) {
-          case 'd':
-            return ParserForXMLSchema.getRange("xml:isDigit", true);
-          case 'D':
-            return ParserForXMLSchema.getRange("xml:isDigit", false);
-          case 'w':
-            return ParserForXMLSchema.getRange("xml:isWord", true);
-          case 'W':
-            return ParserForXMLSchema.getRange("xml:isWord", false);
-          case 's':
-            return ParserForXMLSchema.getRange("xml:isSpace", true);
-          case 'S':
-            return ParserForXMLSchema.getRange("xml:isSpace", false);
-          case 'c':
-            return ParserForXMLSchema.getRange("xml:isNameChar", true);
-          case 'C':
-            return ParserForXMLSchema.getRange("xml:isNameChar", false);
-          case 'i':
-            return ParserForXMLSchema.getRange("xml:isInitialNameChar", true);
-          case 'I':
-            return ParserForXMLSchema.getRange("xml:isInitialNameChar", false);
-          default:
-            throw new RuntimeException("Internal Error: shorthands: \\u"+Integer.toString(ch, 16));
-        }
-    }
-    int decodeEscaped() throws ParseException {
-        if (this.read() != T_BACKSOLIDUS)  throw ex("parser.next.1", this.offset-1);
-        int c = this.chardata;
-        switch (c) {
-          case 'n':  c = '\n';  break; // LINE FEED U+000A
-          case 'r':  c = '\r';  break; // CRRIAGE RETURN U+000D
-          case 't':  c = '\t';  break; // HORIZONTAL TABULATION U+0009
-
-          case 'e':
-          case 'f':
-          case 'x':
-          case 'u':
-          case 'v':
-            throw ex("parser.process.1", this.offset-2);
-          case 'A':
-          case 'Z':
-          case 'z':
-            throw ex("parser.descape.5", this.offset-2);
-          default:
-        }
-        return c;
-    }
-
-    static protected Hashtable ranges = null;
-    static protected Hashtable ranges2 = null;
-    static synchronized protected RangeToken getRange(String name, boolean positive) {
-        if (ranges == null) {
-            ranges = new Hashtable();
-            ranges2 = new Hashtable();
-
-            Token tok = Token.createRange();
-            setupRange(tok, SPACES);
-            ranges.put("xml:isSpace", tok);
-            ranges2.put("xml:isSpace", Token.complementRanges(tok));
-
-            tok = Token.createRange();
-            setupRange(tok, DIGITS);
-            ranges.put("xml:isDigit", tok);
-            ranges2.put("xml:isDigit", Token.complementRanges(tok));
-
-            tok = Token.createRange();
-            setupRange(tok, DIGITS);
-            ranges.put("xml:isDigit", tok);
-            ranges2.put("xml:isDigit", Token.complementRanges(tok));
-
-            tok = Token.createRange();
-            setupRange(tok, LETTERS);
-            tok.mergeRanges((Token)ranges.get("xml:isDigit"));
-            ranges.put("xml:isWord", tok);
-            ranges2.put("xml:isWord", Token.complementRanges(tok));
-
-            tok = Token.createRange();
-            setupRange(tok, NAMECHARS);
-            ranges.put("xml:isNameChar", tok);
-            ranges2.put("xml:isNameChar", Token.complementRanges(tok));
-
-            tok = Token.createRange();
-            setupRange(tok, LETTERS);
-            tok.addRange('_', '_');
-            tok.addRange(':', ':');
-            ranges.put("xml:isInitialNameChar", tok);
-            ranges2.put("xml:isInitialNameChar", Token.complementRanges(tok));
-        }
-        RangeToken tok = positive ? (RangeToken)ranges.get(name)
-            : (RangeToken)ranges2.get(name);
-        return tok;
-    }
-
-    static void setupRange(Token range, String src) {
-        int len = src.length();
-        for (int i = 0;  i < len;  i += 2)
-            range.addRange(src.charAt(i), src.charAt(i+1));
-    }
-
-    private static final String SPACES = "\t\n\r\r  ";
-    private static final String NAMECHARS =
-        "\u002d\u002e\u0030\u003a\u0041\u005a\u005f\u005f\u0061\u007a\u00b7\u00b7\u00c0\u00d6"
-        +"\u00d8\u00f6\u00f8\u0131\u0134\u013e\u0141\u0148\u014a\u017e\u0180\u01c3\u01cd\u01f0"
-        +"\u01f4\u01f5\u01fa\u0217\u0250\u02a8\u02bb\u02c1\u02d0\u02d1\u0300\u0345\u0360\u0361"
-        +"\u0386\u038a\u038c\u038c\u038e\u03a1\u03a3\u03ce\u03d0\u03d6\u03da\u03da\u03dc\u03dc"
-        +"\u03de\u03de\u03e0\u03e0\u03e2\u03f3\u0401\u040c\u040e\u044f\u0451\u045c\u045e\u0481"
-        +"\u0483\u0486\u0490\u04c4\u04c7\u04c8\u04cb\u04cc\u04d0\u04eb\u04ee\u04f5\u04f8\u04f9"
-        +"\u0531\u0556\u0559\u0559\u0561\u0586\u0591\u05a1\u05a3\u05b9\u05bb\u05bd\u05bf\u05bf"
-        +"\u05c1\u05c2\u05c4\u05c4\u05d0\u05ea\u05f0\u05f2\u0621\u063a\u0640\u0652\u0660\u0669"
-        +"\u0670\u06b7\u06ba\u06be\u06c0\u06ce\u06d0\u06d3\u06d5\u06e8\u06ea\u06ed\u06f0\u06f9"
-        +"\u0901\u0903\u0905\u0939\u093c\u094d\u0951\u0954\u0958\u0963\u0966\u096f\u0981\u0983"
-        +"\u0985\u098c\u098f\u0990\u0993\u09a8\u09aa\u09b0\u09b2\u09b2\u09b6\u09b9\u09bc\u09bc"
-        +"\u09be\u09c4\u09c7\u09c8\u09cb\u09cd\u09d7\u09d7\u09dc\u09dd\u09df\u09e3\u09e6\u09f1"
-        +"\u0a02\u0a02\u0a05\u0a0a\u0a0f\u0a10\u0a13\u0a28\u0a2a\u0a30\u0a32\u0a33\u0a35\u0a36"
-        +"\u0a38\u0a39\u0a3c\u0a3c\u0a3e\u0a42\u0a47\u0a48\u0a4b\u0a4d\u0a59\u0a5c\u0a5e\u0a5e"
-        +"\u0a66\u0a74\u0a81\u0a83\u0a85\u0a8b\u0a8d\u0a8d\u0a8f\u0a91\u0a93\u0aa8\u0aaa\u0ab0"
-        +"\u0ab2\u0ab3\u0ab5\u0ab9\u0abc\u0ac5\u0ac7\u0ac9\u0acb\u0acd\u0ae0\u0ae0\u0ae6\u0aef"
-        +"\u0b01\u0b03\u0b05\u0b0c\u0b0f\u0b10\u0b13\u0b28\u0b2a\u0b30\u0b32\u0b33\u0b36\u0b39"
-        +"\u0b3c\u0b43\u0b47\u0b48\u0b4b\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f\u0b61\u0b66\u0b6f"
-        +"\u0b82\u0b83\u0b85\u0b8a\u0b8e\u0b90\u0b92\u0b95\u0b99\u0b9a\u0b9c\u0b9c\u0b9e\u0b9f"
-        +"\u0ba3\u0ba4\u0ba8\u0baa\u0bae\u0bb5\u0bb7\u0bb9\u0bbe\u0bc2\u0bc6\u0bc8\u0bca\u0bcd"
-        +"\u0bd7\u0bd7\u0be7\u0bef\u0c01\u0c03\u0c05\u0c0c\u0c0e\u0c10\u0c12\u0c28\u0c2a\u0c33"
-        +"\u0c35\u0c39\u0c3e\u0c44\u0c46\u0c48\u0c4a\u0c4d\u0c55\u0c56\u0c60\u0c61\u0c66\u0c6f"
-        +"\u0c82\u0c83\u0c85\u0c8c\u0c8e\u0c90\u0c92\u0ca8\u0caa\u0cb3\u0cb5\u0cb9\u0cbe\u0cc4"
-        +"\u0cc6\u0cc8\u0cca\u0ccd\u0cd5\u0cd6\u0cde\u0cde\u0ce0\u0ce1\u0ce6\u0cef\u0d02\u0d03"
-        +"\u0d05\u0d0c\u0d0e\u0d10\u0d12\u0d28\u0d2a\u0d39\u0d3e\u0d43\u0d46\u0d48\u0d4a\u0d4d"
-        +"\u0d57\u0d57\u0d60\u0d61\u0d66\u0d6f\u0e01\u0e2e\u0e30\u0e3a\u0e40\u0e4e\u0e50\u0e59"
-        +"\u0e81\u0e82\u0e84\u0e84\u0e87\u0e88\u0e8a\u0e8a\u0e8d\u0e8d\u0e94\u0e97\u0e99\u0e9f"
-        +"\u0ea1\u0ea3\u0ea5\u0ea5\u0ea7\u0ea7\u0eaa\u0eab\u0ead\u0eae\u0eb0\u0eb9\u0ebb\u0ebd"
-        +"\u0ec0\u0ec4\u0ec6\u0ec6\u0ec8\u0ecd\u0ed0\u0ed9\u0f18\u0f19\u0f20\u0f29\u0f35\u0f35"
-        +"\u0f37\u0f37\u0f39\u0f39\u0f3e\u0f47\u0f49\u0f69\u0f71\u0f84\u0f86\u0f8b\u0f90\u0f95"
-        +"\u0f97\u0f97\u0f99\u0fad\u0fb1\u0fb7\u0fb9\u0fb9\u10a0\u10c5\u10d0\u10f6\u1100\u1100"
-        +"\u1102\u1103\u1105\u1107\u1109\u1109\u110b\u110c\u110e\u1112\u113c\u113c\u113e\u113e"
-        +"\u1140\u1140\u114c\u114c\u114e\u114e\u1150\u1150\u1154\u1155\u1159\u1159\u115f\u1161"
-        +"\u1163\u1163\u1165\u1165\u1167\u1167\u1169\u1169\u116d\u116e\u1172\u1173\u1175\u1175"
-        +"\u119e\u119e\u11a8\u11a8\u11ab\u11ab\u11ae\u11af\u11b7\u11b8\u11ba\u11ba\u11bc\u11c2"
-        +"\u11eb\u11eb\u11f0\u11f0\u11f9\u11f9\u1e00\u1e9b\u1ea0\u1ef9\u1f00\u1f15\u1f18\u1f1d"
-        +"\u1f20\u1f45\u1f48\u1f4d\u1f50\u1f57\u1f59\u1f59\u1f5b\u1f5b\u1f5d\u1f5d\u1f5f\u1f7d"
-        +"\u1f80\u1fb4\u1fb6\u1fbc\u1fbe\u1fbe\u1fc2\u1fc4\u1fc6\u1fcc\u1fd0\u1fd3\u1fd6\u1fdb"
-        +"\u1fe0\u1fec\u1ff2\u1ff4\u1ff6\u1ffc\u20d0\u20dc\u20e1\u20e1\u2126\u2126\u212a\u212b"
-        +"\u212e\u212e\u2180\u2182\u3005\u3005\u3007\u3007\u3021\u302f\u3031\u3035\u3041\u3094"
-        +"\u3099\u309a\u309d\u309e\u30a1\u30fa\u30fc\u30fe\u3105\u312c\u4e00\u9fa5\uac00\ud7a3"
-        +"";
-    private static final String LETTERS =
-        "\u0041\u005a\u0061\u007a\u00c0\u00d6\u00d8\u00f6\u00f8\u0131\u0134\u013e\u0141\u0148"
-        +"\u014a\u017e\u0180\u01c3\u01cd\u01f0\u01f4\u01f5\u01fa\u0217\u0250\u02a8\u02bb\u02c1"
-        +"\u0386\u0386\u0388\u038a\u038c\u038c\u038e\u03a1\u03a3\u03ce\u03d0\u03d6\u03da\u03da"
-        +"\u03dc\u03dc\u03de\u03de\u03e0\u03e0\u03e2\u03f3\u0401\u040c\u040e\u044f\u0451\u045c"
-        +"\u045e\u0481\u0490\u04c4\u04c7\u04c8\u04cb\u04cc\u04d0\u04eb\u04ee\u04f5\u04f8\u04f9"
-        +"\u0531\u0556\u0559\u0559\u0561\u0586\u05d0\u05ea\u05f0\u05f2\u0621\u063a\u0641\u064a"
-        +"\u0671\u06b7\u06ba\u06be\u06c0\u06ce\u06d0\u06d3\u06d5\u06d5\u06e5\u06e6\u0905\u0939"
-        +"\u093d\u093d\u0958\u0961\u0985\u098c\u098f\u0990\u0993\u09a8\u09aa\u09b0\u09b2\u09b2"
-        +"\u09b6\u09b9\u09dc\u09dd\u09df\u09e1\u09f0\u09f1\u0a05\u0a0a\u0a0f\u0a10\u0a13\u0a28"
-        +"\u0a2a\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59\u0a5c\u0a5e\u0a5e\u0a72\u0a74"
-        +"\u0a85\u0a8b\u0a8d\u0a8d\u0a8f\u0a91\u0a93\u0aa8\u0aaa\u0ab0\u0ab2\u0ab3\u0ab5\u0ab9"
-        +"\u0abd\u0abd\u0ae0\u0ae0\u0b05\u0b0c\u0b0f\u0b10\u0b13\u0b28\u0b2a\u0b30\u0b32\u0b33"
-        +"\u0b36\u0b39\u0b3d\u0b3d\u0b5c\u0b5d\u0b5f\u0b61\u0b85\u0b8a\u0b8e\u0b90\u0b92\u0b95"
-        +"\u0b99\u0b9a\u0b9c\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8\u0baa\u0bae\u0bb5\u0bb7\u0bb9"
-        +"\u0c05\u0c0c\u0c0e\u0c10\u0c12\u0c28\u0c2a\u0c33\u0c35\u0c39\u0c60\u0c61\u0c85\u0c8c"
-        +"\u0c8e\u0c90\u0c92\u0ca8\u0caa\u0cb3\u0cb5\u0cb9\u0cde\u0cde\u0ce0\u0ce1\u0d05\u0d0c"
-        +"\u0d0e\u0d10\u0d12\u0d28\u0d2a\u0d39\u0d60\u0d61\u0e01\u0e2e\u0e30\u0e30\u0e32\u0e33"
-        +"\u0e40\u0e45\u0e81\u0e82\u0e84\u0e84\u0e87\u0e88\u0e8a\u0e8a\u0e8d\u0e8d\u0e94\u0e97"
-        +"\u0e99\u0e9f\u0ea1\u0ea3\u0ea5\u0ea5\u0ea7\u0ea7\u0eaa\u0eab\u0ead\u0eae\u0eb0\u0eb0"
-        +"\u0eb2\u0eb3\u0ebd\u0ebd\u0ec0\u0ec4\u0f40\u0f47\u0f49\u0f69\u10a0\u10c5\u10d0\u10f6"
-        +"\u1100\u1100\u1102\u1103\u1105\u1107\u1109\u1109\u110b\u110c\u110e\u1112\u113c\u113c"
-        +"\u113e\u113e\u1140\u1140\u114c\u114c\u114e\u114e\u1150\u1150\u1154\u1155\u1159\u1159"
-        +"\u115f\u1161\u1163\u1163\u1165\u1165\u1167\u1167\u1169\u1169\u116d\u116e\u1172\u1173"
-        +"\u1175\u1175\u119e\u119e\u11a8\u11a8\u11ab\u11ab\u11ae\u11af\u11b7\u11b8\u11ba\u11ba"
-        +"\u11bc\u11c2\u11eb\u11eb\u11f0\u11f0\u11f9\u11f9\u1e00\u1e9b\u1ea0\u1ef9\u1f00\u1f15"
-        +"\u1f18\u1f1d\u1f20\u1f45\u1f48\u1f4d\u1f50\u1f57\u1f59\u1f59\u1f5b\u1f5b\u1f5d\u1f5d"
-        +"\u1f5f\u1f7d\u1f80\u1fb4\u1fb6\u1fbc\u1fbe\u1fbe\u1fc2\u1fc4\u1fc6\u1fcc\u1fd0\u1fd3"
-        +"\u1fd6\u1fdb\u1fe0\u1fec\u1ff2\u1ff4\u1ff6\u1ffc\u2126\u2126\u212a\u212b\u212e\u212e"
-        +"\u2180\u2182\u3007\u3007\u3021\u3029\u3041\u3094\u30a1\u30fa\u3105\u312c\u4e00\u9fa5"
-        +"\uac00\ud7a3";
-    private static final String DIGITS =
-        "\u0030\u0039\u0660\u0669\u06F0\u06F9\u0966\u096F\u09E6\u09EF\u0A66\u0A6F\u0AE6\u0AEF"
-        +"\u0B66\u0B6F\u0BE7\u0BEF\u0C66\u0C6F\u0CE6\u0CEF\u0D66\u0D6F\u0E50\u0E59\u0ED0\u0ED9"
-        +"\u0F20\u0F29";
-}
diff --git a/src/org/apache/xerces/utils/regex/REUtil.java b/src/org/apache/xerces/utils/regex/REUtil.java
deleted file mode 100644
index 683b83e..0000000
--- a/src/org/apache/xerces/utils/regex/REUtil.java
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils.regex;
-
-
-import java.text.CharacterIterator;
-
-public final class REUtil {
-    private REUtil() {
-    }
-
-    static final int composeFromSurrogates(int high, int low) {
-        return 0x10000 + ((high-0xd800)<<10) + low-0xdc00;
-    }
-
-    static final boolean isLowSurrogate(int ch) {
-        return (ch & 0xfc00) == 0xdc00;
-    }
-
-    static final boolean isHighSurrogate(int ch) {
-        return (ch & 0xfc00) == 0xd800;
-    }
-
-    static final String decomposeToSurrogates(int ch) {
-        char[] chs = new char[2];
-        ch -= 0x10000;
-        chs[0] = (char)((ch>>10)+0xd800);
-        chs[1] = (char)((ch&0x3ff)+0xdc00);
-        return new String(chs);
-    }
-
-    static final String substring(CharacterIterator iterator, int begin, int end) {
-        char[] src = new char[end-begin];
-        for (int i = 0;  i < src.length;  i ++)
-            src[i] = iterator.setIndex(i+begin);
-        return new String(src);
-    }
-
-    // ================================================================
-
-    static final int getOptionValue(int ch) {
-        int ret = 0;
-        switch (ch) {
-          case 'i':
-            ret = RegularExpression.IGNORE_CASE;
-            break;
-          case 'm':
-            ret = RegularExpression.MULTIPLE_LINES;
-            break;
-          case 's':
-            ret = RegularExpression.SINGLE_LINE;
-            break;
-          case 'x':
-            ret = RegularExpression.EXTENDED_COMMENT;
-            break;
-          case 'u':
-            ret = RegularExpression.USE_UNICODE_CATEGORY;
-            break;
-          case 'w':
-            ret = RegularExpression.UNICODE_WORD_BOUNDARY;
-            break;
-          case 'F':
-            ret = RegularExpression.PROHIBIT_FIXED_STRING_OPTIMIZATION;
-            break;
-          case 'H':
-            ret = RegularExpression.PROHIBIT_HEAD_CHARACTER_OPTIMIZATION;
-            break;
-          case 'X':
-            ret = RegularExpression.XMLSCHEMA_MODE;
-            break;
-          case ',':
-            ret = RegularExpression.SPECIAL_COMMA;
-            break;
-          default:
-        }
-        return ret;
-    }
-
-    static final int parseOptions(String opts) throws ParseException {
-        if (opts == null)  return 0;
-        int options = 0;
-        for (int i = 0;  i < opts.length();  i ++) {
-            int v = getOptionValue(opts.charAt(i));
-            if (v == 0)
-                throw new ParseException("Unknown Option: "+opts.substring(i), -1);
-            options |= v;
-        }
-        return options;
-    }
-
-    static final String createOptionString(int options) {
-        StringBuffer sb = new StringBuffer(9);
-        if ((options & RegularExpression.PROHIBIT_FIXED_STRING_OPTIMIZATION) != 0)
-            sb.append((char)'F');
-        if ((options & RegularExpression.PROHIBIT_HEAD_CHARACTER_OPTIMIZATION) != 0)
-            sb.append((char)'H');
-        if ((options & RegularExpression.XMLSCHEMA_MODE) != 0)
-            sb.append((char)'X');
-        if ((options & RegularExpression.IGNORE_CASE) != 0)
-            sb.append((char)'i');
-        if ((options & RegularExpression.MULTIPLE_LINES) != 0)
-            sb.append((char)'m');
-        if ((options & RegularExpression.SINGLE_LINE) != 0)
-            sb.append((char)'s');
-        if ((options & RegularExpression.USE_UNICODE_CATEGORY) != 0)
-            sb.append((char)'u');
-        if ((options & RegularExpression.UNICODE_WORD_BOUNDARY) != 0)
-            sb.append((char)'w');
-        if ((options & RegularExpression.EXTENDED_COMMENT) != 0)
-            sb.append((char)'x');
-        if ((options & RegularExpression.SPECIAL_COMMA) != 0)
-            sb.append((char)',');
-        return sb.toString().intern();
-    }
-
-    // ================================================================
-
-    static String stripExtendedComment(String regex) {
-        int len = regex.length();
-        StringBuffer buffer = new StringBuffer(len);
-        int offset = 0;
-        while (offset < len) {
-            int ch = regex.charAt(offset++);
-                                                // Skips a white space.
-            if (ch == '\t' || ch == '\n' || ch == '\f' || ch == '\r' || ch == ' ')
-                continue;
-
-            if (ch == '#') {                    // Skips chracters between '#' and a line end.
-                while (offset < len) {
-                    ch = regex.charAt(offset++);
-                    if (ch == '\r' || ch == '\n')
-                        break;
-                }
-                continue;
-            }
-
-            int next;                           // Strips an escaped white space.
-            if (ch == '\\' && offset < len) {
-                if ((next = regex.charAt(offset)) == '#'
-                    || next == '\t' || next == '\n' || next == '\f'
-                    || next == '\r' || next == ' ') {
-                    buffer.append((char)next);
-                    offset ++;
-                } else {                        // Other escaped character.
-                    buffer.append((char)'\\');
-                    buffer.append((char)next);
-                    offset ++;
-                }
-            } else                              // As is.
-                buffer.append((char)ch);
-        }
-        return buffer.toString();
-    }
-
-    // ================================================================
-
-    /**
-     * Sample entry.
-     * <div>Usage: <KBD>org.apache.xerces.utils.regex.REUtil &lt;regex&gt; &lt;string&gt;</KBD></div>
-     */
-    public static void main(String[] argv) {
-        String pattern = null;
-        try {
-            String options = "";
-            String target = null;
-            if( argv.length == 0 ) {
-                System.out.println( "Error:Usage: java REUtil -i|-m|-s|-u|-w|-X regularExpression String" );
-                System.exit( 0 );
-            }
-            for (int i = 0;  i < argv.length;  i ++) {
-                if (argv[i].length() == 0 || argv[i].charAt(0) != '-') {
-                    if (pattern == null)
-                        pattern = argv[i];
-                    else if (target == null)
-                        target = argv[i];
-                    else
-                        System.err.println("Unnecessary: "+argv[i]);
-                } else if (argv[i].equals("-i")) {
-                    options += "i";
-                } else if (argv[i].equals("-m")) {
-                    options += "m";
-                } else if (argv[i].equals("-s")) {
-                    options += "s";
-                } else if (argv[i].equals("-u")) {
-                    options += "u";
-                } else if (argv[i].equals("-w")) {
-                    options += "w";
-                } else if (argv[i].equals("-X")) {
-                    options += "X";
-                } else {
-                    System.err.println("Unknown option: "+argv[i]);
-                }
-            }
-            RegularExpression reg = new RegularExpression(pattern, options);
-            System.out.println("RegularExpression: "+reg);
-            Match match = new Match();
-            reg.matches(target, match);
-            for (int i = 0;  i < match.getNumberOfGroups();  i ++) {
-                if (i == 0 )  System.out.print("Matched range for the whole pattern: ");
-                else System.out.print("["+i+"]: ");
-                if (match.getBeginning(i) < 0)
-                    System.out.println("-1");
-                else {
-                    System.out.print(match.getBeginning(i)+", "+match.getEnd(i)+", ");
-                    System.out.println("\""+match.getCapturedText(i)+"\"");
-                }
-            }
-        } catch (ParseException pe) {
-            if (pattern == null) {
-                pe.printStackTrace();
-            } else {
-                System.err.println("org.apache.xerces.utils.regex.ParseException: "+pe.getMessage());
-                String indent = "        ";
-                System.err.println(indent+pattern);
-                int loc = pe.getLocation();
-                if (loc >= 0) {
-                    System.err.print(indent);
-                    for (int i = 0;  i < loc;  i ++)  System.err.print("-");
-                    System.err.println("^");
-                }
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    static final int CACHESIZE = 20;
-    static RegularExpression[] regexCache = new RegularExpression[CACHESIZE];
-    /**
-     * Creates a RegularExpression instance.
-     * This method caches created instances.
-     *
-     * @see org.apache.xerces.utils.regex.RegularExpression#RegularExpression(java.lang.String, java.lang.String)
-     */
-    public static RegularExpression createRegex(String pattern, String options)
-        throws ParseException {
-        RegularExpression re = null;
-        int intOptions = REUtil.parseOptions(options);
-        synchronized (REUtil.regexCache) {
-            int i;
-            for (i = 0;  i < REUtil.CACHESIZE;  i ++) {
-                re = REUtil.regexCache[i];
-                if (re == null) {
-                    i = -1;
-                    break;
-                }
-                if (re.equals(pattern, intOptions))
-                    break;
-            }
-            if (re != null) {
-                if (i != 0) {
-                    System.arraycopy(REUtil.regexCache, 0, REUtil.regexCache, 1, i);
-                    REUtil.regexCache[0] = re;
-                }
-            } else {
-                re = new RegularExpression(pattern, options);
-                System.arraycopy(REUtil.regexCache, 0, REUtil.regexCache, 1, REUtil.CACHESIZE-1);
-                REUtil.regexCache[0] = re;
-            }
-        }
-        return re;
-    }
-
-    /**
-     *
-     * @see org.apache.xerces.utils.regex.RegularExpression#matches(java.lang.String)
-     */
-    public static boolean matches(String regex, String target) throws ParseException {
-        return REUtil.createRegex(regex, null).matches(target);
-    }
-
-    /**
-     *
-     * @see org.apache.xerces.utils.regex.RegularExpression#matches(java.lang.String)
-     */
-    public static boolean matches(String regex, String options, String target) throws ParseException {
-        return REUtil.createRegex(regex, options).matches(target);
-    }
-
-    // ================================================================
-
-    /**
-     *
-     */
-    public static String quoteMeta(String literal) {
-        int len = literal.length();
-        StringBuffer buffer = null;
-        for (int i = 0;  i < len;  i ++) {
-            int ch = literal.charAt(i);
-            if (".*+?{[()|\\^$".indexOf(ch) >= 0) {
-                if (buffer == null) {
-                    buffer = new StringBuffer(i+(len-i)*2);
-                    if (i > 0)  buffer.append(literal.substring(0, i));
-                }
-                buffer.append((char)'\\');
-            } else if (buffer != null)
-                buffer.append((char)ch);
-        }
-        return buffer != null ? buffer.toString() : literal;
-    }
-
-    // ================================================================
-
-    static void dumpString(String v) {
-        for (int i = 0;  i < v.length();  i ++) {
-            System.out.print(Integer.toHexString(v.charAt(i)));
-            System.out.print(" ");
-        }
-        System.out.println();
-    }
-}
diff --git a/src/org/apache/xerces/utils/regex/RangeToken.java b/src/org/apache/xerces/utils/regex/RangeToken.java
deleted file mode 100644
index 976f8e6..0000000
--- a/src/org/apache/xerces/utils/regex/RangeToken.java
+++ /dev/null
@@ -1,652 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils.regex;
-
-
-/**
- * This class represents a character class such as [a-z] or a period.
- */
-final class RangeToken extends Token implements java.io.Serializable {
-
-    int[] ranges;
-    boolean sorted;
-    boolean compacted;
-    RangeToken icaseCache = null;
-    int[] map = null;
-    int nonMapIndex;
-
-    RangeToken(int type) {
-        super(type);
-        this.setSorted(false);
-    }
-
-                                                // for RANGE or NRANGE
-    protected void addRange(int start, int end) {
-        this.icaseCache = null;
-        //System.err.println("Token#addRange(): "+start+" "+end);
-        int r1, r2;
-        if (start <= end) {
-            r1 = start;
-            r2 = end;
-        } else {
-            r1 = end;
-            r2 = start;
-        }
-
-        int pos = 0;
-        if (this.ranges == null) {
-            this.ranges = new int[2];
-            this.ranges[0] = r1;
-            this.ranges[1] = r2;
-            this.setSorted(true);
-        } else {
-            pos = this.ranges.length;
-            if (this.ranges[pos-1]+1 == r1) {
-                this.ranges[pos-1] = r2;
-                return;
-            }
-            int[] temp = new int[pos+2];
-            System.arraycopy(this.ranges, 0, temp, 0, pos);
-            this.ranges = temp;
-            if (this.ranges[pos-1] >= r1)
-                this.setSorted(false);
-            this.ranges[pos++] = r1;
-            this.ranges[pos] = r2;
-            if (!this.sorted)
-                this.sortRanges();
-        }
-    }
-
-    private final boolean isSorted() {
-        return this.sorted;
-    }
-    private final void setSorted(boolean sort) {
-        this.sorted = sort;
-        if (!sort)  this.compacted = false;
-    }
-    private final boolean isCompacted() {
-        return this.compacted;
-    }
-    private final void setCompacted() {
-        this.compacted = true;
-    }
-
-    protected void sortRanges() {
-        if (this.isSorted())
-            return;
-        if (this.ranges == null)
-            return;
-        //System.err.println("Do sorting: "+this.ranges.length);
-
-                                                // Bubble sort
-                                                // Why? -- In many cases,
-                                                //         this.ranges has few elements.
-        for (int i = this.ranges.length-4;  i >= 0;  i -= 2) {
-            for (int j = 0;  j <= i;  j += 2) {
-                if (this.ranges[j] > this.ranges[j+2]
-                    || this.ranges[j] == this.ranges[j+2] && this.ranges[j+1] > this.ranges[j+3]) {
-                    int tmp;
-                    tmp = this.ranges[j+2];
-                    this.ranges[j+2] = this.ranges[j];
-                    this.ranges[j] = tmp;
-                    tmp = this.ranges[j+3];
-                    this.ranges[j+3] = this.ranges[j+1];
-                    this.ranges[j+1] = tmp;
-                }
-            }
-        }
-        this.setSorted(true);
-    }
-
-    /**
-     * this.ranges is sorted.
-     */
-    protected void compactRanges() {
-        boolean DEBUG = false;
-        if (this.ranges == null || this.ranges.length <= 2)
-            return;
-        if (this.isCompacted())
-            return;
-        int base = 0;                           // Index of writing point
-        int target = 0;                         // Index of processing point
-
-        while (target < this.ranges.length) {
-            if (base != target) {
-                this.ranges[base] = this.ranges[target++];
-                this.ranges[base+1] = this.ranges[target++];
-            } else
-                target += 2;
-            int baseend = this.ranges[base+1];
-            while (target < this.ranges.length) {
-                if (baseend+1 < this.ranges[target])
-                    break;
-                if (baseend+1 == this.ranges[target]) {
-                    if (DEBUG)
-                        System.err.println("Token#compactRanges(): Compaction: ["+this.ranges[base]
-                                           +", "+this.ranges[base+1]
-                                           +"], ["+this.ranges[target]
-                                           +", "+this.ranges[target+1]
-                                           +"] -> ["+this.ranges[base]
-                                           +", "+this.ranges[target+1]
-                                           +"]");
-                    this.ranges[base+1] = this.ranges[target+1];
-                    baseend = this.ranges[base+1];
-                    target += 2;
-                } else if (baseend >= this.ranges[target+1]) {
-                    if (DEBUG)
-                        System.err.println("Token#compactRanges(): Compaction: ["+this.ranges[base]
-                                           +", "+this.ranges[base+1]
-                                           +"], ["+this.ranges[target]
-                                           +", "+this.ranges[target+1]
-                                           +"] -> ["+this.ranges[base]
-                                           +", "+this.ranges[base+1]
-                                           +"]");
-                    target += 2;
-                } else if (baseend < this.ranges[target+1]) {
-                    if (DEBUG)
-                        System.err.println("Token#compactRanges(): Compaction: ["+this.ranges[base]
-                                           +", "+this.ranges[base+1]
-                                           +"], ["+this.ranges[target]
-                                           +", "+this.ranges[target+1]
-                                           +"] -> ["+this.ranges[base]
-                                           +", "+this.ranges[target+1]
-                                           +"]");
-                    this.ranges[base+1] = this.ranges[target+1];
-                    baseend = this.ranges[base+1];
-                    target += 2;
-                } else {
-                    throw new RuntimeException("Token#compactRanges(): Internel Error: ["
-                                               +this.ranges[base]
-                                               +","+this.ranges[base+1]
-                                               +"] ["+this.ranges[target]
-                                               +","+this.ranges[target+1]+"]");
-                }
-            } // while
-            base += 2;
-        }
-
-        if (base != this.ranges.length) {
-            int[] result = new int[base];
-            System.arraycopy(this.ranges, 0, result, 0, base);
-            this.ranges = result;
-        }
-        this.setCompacted();
-    }
-
-    protected void mergeRanges(Token token) {
-        if (token.type != this.type)
-            throw new IllegalArgumentException("Token#mergeRanges(): Mismatched Type: "+token.type);
-        RangeToken tok = (RangeToken)token;
-        this.sortRanges();
-        tok.sortRanges();
-        if (tok.ranges == null)
-            return;
-        this.icaseCache = null;
-        this.setSorted(true);
-        if (this.ranges == null) {
-            this.ranges = new int[tok.ranges.length];
-            System.arraycopy(tok.ranges, 0, this.ranges, 0, tok.ranges.length);
-            return;
-        }
-        int[] result = new int[this.ranges.length+tok.ranges.length];
-        for (int i = 0, j = 0, k = 0;  i < this.ranges.length || j < tok.ranges.length;) {
-            if (i >= this.ranges.length) {
-                result[k++] = tok.ranges[j++];
-                result[k++] = tok.ranges[j++];
-            } else if (j >= tok.ranges.length) {
-                result[k++] = this.ranges[i++];
-                result[k++] = this.ranges[i++];
-            } else if (tok.ranges[j] < this.ranges[i]
-                       || tok.ranges[j] == this.ranges[i] && tok.ranges[j+1] < this.ranges[i+1]) {
-                result[k++] = tok.ranges[j++];
-                result[k++] = tok.ranges[j++];
-            } else {
-                result[k++] = this.ranges[i++];
-                result[k++] = this.ranges[i++];
-            }
-        }
-        this.ranges = result;
-    }
-
-    protected void subtractRanges(Token token) {
-        if (token.type == NRANGE) {
-            this.intersectRanges(token);
-            return;
-        }
-        RangeToken tok = (RangeToken)token;
-        if (tok.ranges == null || this.ranges == null)
-            return;
-        this.icaseCache = null;
-        this.sortRanges();
-        this.compactRanges();
-        tok.sortRanges();
-        tok.compactRanges();
-
-        //System.err.println("Token#substractRanges(): Entry: "+this.ranges.length+", "+tok.ranges.length);
-
-        int[] result = new int[this.ranges.length+tok.ranges.length];
-        int wp = 0, src = 0, sub = 0;
-        while (src < this.ranges.length && sub < tok.ranges.length) {
-            int srcbegin = this.ranges[src];
-            int srcend = this.ranges[src+1];
-            int subbegin = tok.ranges[sub];
-            int subend = tok.ranges[sub+1];
-            if (srcend < subbegin) {            // Not overlapped
-                                                // src: o-----o
-                                                // sub:         o-----o
-                                                // res: o-----o
-                                                // Reuse sub
-                result[wp++] = this.ranges[src++];
-                result[wp++] = this.ranges[src++];
-            } else if (srcend >= subbegin
-                       && srcbegin <= subend) { // Overlapped
-                                                // src:    o--------o
-                                                // sub:  o----o
-                                                // sub:      o----o
-                                                // sub:          o----o
-                                                // sub:  o------------o
-                if (subbegin <= srcbegin && srcend <= subend) {
-                                                // src:    o--------o
-                                                // sub:  o------------o
-                                                // res: empty
-                                                // Reuse sub
-                    src += 2;
-                } else if (subbegin <= srcbegin) {
-                                                // src:    o--------o
-                                                // sub:  o----o
-                                                // res:       o-----o
-                                                // Reuse src(=res)
-                    this.ranges[src] = subend+1;
-                    sub += 2;
-                } else if (srcend <= subend) {
-                                                // src:    o--------o
-                                                // sub:          o----o
-                                                // res:    o-----o
-                                                // Reuse sub
-                    result[wp++] = srcbegin;
-                    result[wp++] = subbegin-1;
-                    src += 2;
-                } else {
-                                                // src:    o--------o
-                                                // sub:      o----o
-                                                // res:    o-o    o-o
-                                                // Reuse src(=right res)
-                    result[wp++] = srcbegin;
-                    result[wp++] = subbegin-1;
-                    this.ranges[src] = subend+1;
-                    sub += 2;
-                }
-            } else if (subend < srcbegin) {
-                                                // Not overlapped
-                                                // src:          o-----o
-                                                // sub: o----o
-                sub += 2;
-            } else {
-                throw new RuntimeException("Token#subtractRanges(): Internal Error: ["+this.ranges[src]
-                                           +","+this.ranges[src+1]
-                                           +"] - ["+tok.ranges[sub]
-                                           +","+tok.ranges[sub+1]
-                                           +"]");
-            }
-        }
-        while (src < this.ranges.length) {
-            result[wp++] = this.ranges[src++];
-            result[wp++] = this.ranges[src++];
-        }
-        this.ranges = new int[wp];
-        System.arraycopy(result, 0, this.ranges, 0, wp);
-                                                // this.ranges is sorted and compacted.
-    }
-
-    /**
-     * @param tok Ignore whether it is NRANGE or not.
-     */
-    protected void intersectRanges(Token token) {
-        RangeToken tok = (RangeToken)token;
-        if (tok.ranges == null || this.ranges == null)
-            return;
-        this.icaseCache = null;
-        this.sortRanges();
-        this.compactRanges();
-        tok.sortRanges();
-        tok.compactRanges();
-
-        int[] result = new int[this.ranges.length+tok.ranges.length];
-        int wp = 0, src1 = 0, src2 = 0;
-        while (src1 < this.ranges.length && src2 < tok.ranges.length) {
-            int src1begin = this.ranges[src1];
-            int src1end = this.ranges[src1+1];
-            int src2begin = tok.ranges[src2];
-            int src2end = tok.ranges[src2+1];
-            if (src1end < src2begin) {          // Not overlapped
-                                                // src1: o-----o
-                                                // src2:         o-----o
-                                                // res:  empty
-                                                // Reuse src2
-                src1 += 2;
-            } else if (src1end >= src2begin
-                       && src1begin <= src2end) { // Overlapped
-                                                // src1:    o--------o
-                                                // src2:  o----o
-                                                // src2:      o----o
-                                                // src2:          o----o
-                                                // src2:  o------------o
-                if (src2begin <= src2begin && src1end <= src2end) {
-                                                // src1:    o--------o
-                                                // src2:  o------------o
-                                                // res:     o--------o
-                                                // Reuse src2
-                    result[wp++] = src1begin;
-                    result[wp++] = src1end;
-                    src1 += 2;
-                } else if (src2begin <= src1begin) {
-                                                // src1:    o--------o
-                                                // src2:  o----o
-                                                // res:     o--o
-                                                // Reuse the rest of src1
-                    result[wp++] = src1begin;
-                    result[wp++] = src2end;
-                    this.ranges[src1] = src2end+1;
-                    src2 += 2;
-                } else if (src1end <= src2end) {
-                                                // src1:    o--------o
-                                                // src2:          o----o
-                                                // res:           o--o
-                                                // Reuse src2
-                    result[wp++] = src2begin;
-                    result[wp++] = src1end;
-                    src1 += 2;
-                } else {
-                                                // src1:    o--------o
-                                                // src2:      o----o
-                                                // res:       o----o
-                                                // Reuse the rest of src1
-                    result[wp++] = src2begin;
-                    result[wp++] = src2end;
-                    this.ranges[src1] = src2end+1;
-                }
-            } else if (src2end < src1begin) {
-                                                // Not overlapped
-                                                // src1:          o-----o
-                                                // src2: o----o
-                src2 += 2;
-            } else {
-                throw new RuntimeException("Token#intersectRanges(): Internal Error: ["
-                                           +this.ranges[src1]
-                                           +","+this.ranges[src1+1]
-                                           +"] & ["+tok.ranges[src2]
-                                           +","+tok.ranges[src2+1]
-                                           +"]");
-            }
-        }
-        while (src1 < this.ranges.length) {
-            result[wp++] = this.ranges[src1++];
-            result[wp++] = this.ranges[src1++];
-        }
-        this.ranges = new int[wp];
-        System.arraycopy(result, 0, this.ranges, 0, wp);
-                                                // this.ranges is sorted and compacted.
-    }
-
-    /**
-     * for RANGE: Creates complement.
-     * for NRANGE: Creates the same meaning RANGE.
-     */
-    static Token complementRanges(Token token) {
-        if (token.type != RANGE && token.type != NRANGE)
-            throw new IllegalArgumentException("Token#complementRanges(): must be RANGE: "+token.type);
-        RangeToken tok = (RangeToken)token;
-        tok.sortRanges();
-        tok.compactRanges();
-        int len = tok.ranges.length+2;
-        if (tok.ranges[0] == 0)
-            len -= 2;
-        int last = tok.ranges[tok.ranges.length-1];
-        if (last == UTF16_MAX)
-            len -= 2;
-        RangeToken ret = Token.createRange();
-        ret.ranges = new int[len];
-        int wp = 0;
-        if (tok.ranges[0] > 0) {
-            ret.ranges[wp++] = 0;
-            ret.ranges[wp++] = tok.ranges[0]-1;
-        }
-        for (int i = 1;  i < tok.ranges.length-2;  i += 2) {
-            ret.ranges[wp++] = tok.ranges[i]+1;
-            ret.ranges[wp++] = tok.ranges[i+1]-1;
-        }
-        if (last != UTF16_MAX) {
-            ret.ranges[wp++] = last+1;
-            ret.ranges[wp] = UTF16_MAX;
-        }
-        ret.setCompacted();
-        return ret;
-    }
-
-    synchronized RangeToken getCaseInsensitiveToken() {
-        if (this.icaseCache != null)
-            return this.icaseCache;
-            
-        RangeToken uppers = this.type == Token.RANGE ? Token.createRange() : Token.createNRange();
-        for (int i = 0;  i < this.ranges.length;  i += 2) {
-            for (int ch = this.ranges[i];  ch <= this.ranges[i+1];  ch ++) {
-                if (ch > 0xffff)
-                    uppers.addRange(ch, ch);
-                else {
-                    char uch = Character.toUpperCase((char)ch);
-                    uppers.addRange(uch, uch);
-                }
-            }
-        }
-        RangeToken lowers = this.type == Token.RANGE ? Token.createRange() : Token.createNRange();
-        for (int i = 0;  i < uppers.ranges.length;  i += 2) {
-            for (int ch = uppers.ranges[i];  ch <= uppers.ranges[i+1];  ch ++) {
-                if (ch > 0xffff)
-                    lowers.addRange(ch, ch);
-                else {
-                    char uch = Character.toUpperCase((char)ch);
-                    lowers.addRange(uch, uch);
-                }
-            }
-        }
-        lowers.mergeRanges(uppers);
-        lowers.mergeRanges(this);
-        lowers.compactRanges();
-
-        this.icaseCache = lowers;
-        return lowers;
-    }
-
-    void dumpRanges() {
-        System.err.print("RANGE: ");
-        if (this.ranges == null)
-            System.err.println(" NULL");
-        for (int i = 0;  i < this.ranges.length;  i += 2) {
-            System.err.print("["+this.ranges[i]+","+this.ranges[i+1]+"] ");
-        }
-        System.err.println("");
-    }
-
-    boolean match(int ch) {
-        if (this.map == null)  this.createMap();
-        boolean ret;
-        if (this.type == RANGE) {
-            if (ch < MAPSIZE)
-                return (this.map[ch/32] & (1<<(ch&0x1f))) != 0;
-            ret = false;
-            for (int i = this.nonMapIndex;  i < this.ranges.length;  i += 2) {
-                if (this.ranges[i] <= ch && ch <= this.ranges[i+1])
-                    return true;
-            }
-        } else {
-            if (ch < MAPSIZE)
-                return (this.map[ch/32] & (1<<(ch&0x1f))) == 0;
-            ret = true;
-            for (int i = this.nonMapIndex;  i < this.ranges.length;  i += 2) {
-                if (this.ranges[i] <= ch && ch <= this.ranges[i+1])
-                    return false;
-            }
-        }
-        return ret;
-    }
-
-    private static final int MAPSIZE = 256;
-    private void createMap() {
-        int asize = MAPSIZE/32;                 // 32 is the number of bits in `int'.
-        this.map = new int[asize];
-        this.nonMapIndex = this.ranges.length;
-        for (int i = 0;  i < asize;  i ++)  this.map[i] = 0;
-        for (int i = 0;  i < this.ranges.length;  i += 2) {
-            int s = this.ranges[i];
-            int e = this.ranges[i+1];
-            if (s < MAPSIZE) {
-                for (int j = s;  j <= e && j < MAPSIZE;  j ++)
-                    this.map[j/32] |= 1<<(j&0x1f); // s&0x1f : 0-31
-            } else {
-                this.nonMapIndex = i;
-                break;
-            }
-            if (e >= MAPSIZE) {
-                this.nonMapIndex = i;
-                break;
-            }
-        }
-        //for (int i = 0;  i < asize;  i ++)  System.err.println("Map: "+Integer.toString(this.map[i], 16));
-    }
-
-    public String toString(int options) {
-        String ret;
-        if (this.type == RANGE) {
-            if (this == Token.token_dot)
-                ret = ".";
-            else if (this == Token.token_0to9)
-                ret = "\\d";
-            else if (this == Token.token_wordchars)
-                ret = "\\w";
-            else if (this == Token.token_spaces)
-                ret = "\\s";
-            else {
-                StringBuffer sb = new StringBuffer();
-                sb.append("[");
-                for (int i = 0;  i < this.ranges.length;  i += 2) {
-                    if ((options & RegularExpression.SPECIAL_COMMA) != 0 && i > 0)  sb.append(",");
-                    if (this.ranges[i] == this.ranges[i+1]) {
-                        sb.append(escapeCharInCharClass(this.ranges[i]));
-                    } else {
-                        sb.append(escapeCharInCharClass(this.ranges[i]));
-                        sb.append((char)'-');
-                        sb.append(escapeCharInCharClass(this.ranges[i+1]));
-                    }
-                }
-                sb.append("]");
-                ret = sb.toString();
-            }
-        } else {
-            if (this == Token.token_not_0to9)
-                ret = "\\D";
-            else if (this == Token.token_not_wordchars)
-                ret = "\\W";
-            else if (this == Token.token_not_spaces)
-                ret = "\\S";
-            else {
-                StringBuffer sb = new StringBuffer();
-                sb.append("[^");
-                for (int i = 0;  i < this.ranges.length;  i += 2) {
-                    if ((options & RegularExpression.SPECIAL_COMMA) != 0 && i > 0)  sb.append(",");
-                    if (this.ranges[i] == this.ranges[i+1]) {
-                        sb.append(escapeCharInCharClass(this.ranges[i]));
-                    } else {
-                        sb.append(escapeCharInCharClass(this.ranges[i]));
-                        sb.append('-');
-                        sb.append(escapeCharInCharClass(this.ranges[i+1]));
-                    }
-                }
-                sb.append("]");
-                ret = sb.toString();
-            }
-        }
-        return ret;
-    }
-
-    private static String escapeCharInCharClass(int ch) {
-        String ret;
-        switch (ch) {
-          case '[':  case ']':  case '-':  case '^':
-          case ',':  case '\\':
-            ret = "\\"+(char)ch;
-            break;
-          case '\f':  ret = "\\f";  break;
-          case '\n':  ret = "\\n";  break;
-          case '\r':  ret = "\\r";  break;
-          case '\t':  ret = "\\t";  break;
-          case 0x1b:  ret = "\\e";  break;
-          //case 0x0b:  ret = "\\v";  break;
-          default:
-            if (ch < 0x20) {
-                String pre = "0"+Integer.toHexString(ch);
-                ret = "\\x"+pre.substring(pre.length()-2, pre.length());
-            } else if (ch >= 0x10000) {
-                String pre = "0"+Integer.toHexString(ch);
-                ret = "\\v"+pre.substring(pre.length()-6, pre.length());
-            } else
-                ret = ""+(char)ch;
-        }
-        return ret;
-    }
-
-}
diff --git a/src/org/apache/xerces/utils/regex/RegexParser.java b/src/org/apache/xerces/utils/regex/RegexParser.java
deleted file mode 100644
index 1e0c177..0000000
--- a/src/org/apache/xerces/utils/regex/RegexParser.java
+++ /dev/null
@@ -1,1273 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils.regex;
-
-
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-import java.util.Vector;
-
-/**
- * A Regular Expression Parser.
- */
-class RegexParser {
-    static final int T_CHAR = 0;
-    static final int T_EOF = 1;
-    static final int T_OR = 2;                  // '|'
-    static final int T_STAR = 3;                // '*'
-    static final int T_PLUS = 4;                // '+'
-    static final int T_QUESTION = 5;            // '?'
-    static final int T_LPAREN = 6;              // '('
-    static final int T_RPAREN = 7;              // ')'
-    static final int T_DOT = 8;                 // '.'
-    static final int T_LBRACKET = 9;            // '['
-    static final int T_BACKSOLIDUS = 10;        // '\'
-    static final int T_CARET = 11;              // '^'
-    static final int T_DOLLAR = 12;             // '$'
-    static final int T_LPAREN2 = 13;            // '(?:'
-    static final int T_LOOKAHEAD = 14;          // '(?='
-    static final int T_NEGATIVELOOKAHEAD = 15;  // '(?!'
-    static final int T_LOOKBEHIND = 16;         // '(?<='
-    static final int T_NEGATIVELOOKBEHIND = 17; // '(?<!'
-    static final int T_INDEPENDENT = 18;        // '(?>'
-    static final int T_SET_OPERATIONS = 19;     // '(?['
-    static final int T_POSIX_CHARCLASS_START = 20; // '[:' in a character class
-    static final int T_COMMENT = 21;            // '(?#'
-    static final int T_MODIFIERS = 22;          // '(?' [\-,a-z,A-Z]
-    static final int T_CONDITION = 23;          // '(?('
-    static final int T_XMLSCHEMA_CC_SUBTRACTION = 24; // '-[' in a character class
-
-    static class ReferencePosition {
-        int refNumber;
-        int position;
-        ReferencePosition(int n, int pos) {
-            this.refNumber = n;
-            this.position = pos;
-        }
-    }
-
-    int offset;
-    String regex;
-    int regexlen;
-    int options;
-    ResourceBundle resources;
-    int chardata;
-    int nexttoken;
-    static protected final int S_NORMAL = 0;
-    static protected final int S_INBRACKETS = 1;
-    static protected final int S_INXBRACKETS = 2;
-    int context = S_NORMAL;
-    int parennumber = 1;
-    boolean hasBackReferences;
-    Vector references = null;
-
-    public RegexParser() {
-        //TODO IBM-JR this.setLocale(Locale.getDefault());
-    }
-    public RegexParser(Locale locale) {
-        //TODO IBM-JR this.setLocale(locale);
-    }
-
-    public void setLocale(Locale locale) {
-        try {
-            this.resources = ResourceBundle.getBundle("org.apache.xerces.utils.regex.message", locale);
-        } catch (MissingResourceException mre) {
-            throw new RuntimeException("Installation Problem???  Couldn't load messages: "
-                                       +mre.getMessage());
-        }
-    }
-
-    final ParseException ex(String key, int loc) {
-        return new ParseException(this.resources.getString(key), loc);
-    }
-
-    private final boolean isSet(int flag) {
-        return (this.options & flag) == flag;
-    }
-
-    synchronized Token parse(String regex, int options) throws ParseException {
-        this.options = options;
-        this.offset = 0;
-        this.setContext(S_NORMAL);
-        this.parennumber = 1;
-        this.hasBackReferences = false;
-        this.regex = regex;
-        if (this.isSet(RegularExpression.EXTENDED_COMMENT))
-            this.regex = REUtil.stripExtendedComment(this.regex);
-        this.regexlen = this.regex.length();
-
-
-        this.next();
-        Token ret = this.parseRegex();
-        if (this.offset != this.regexlen)
-            throw ex("parser.parse.1", this.offset);
-        if (this.references != null) {
-            for (int i = 0;  i < this.references.size();  i ++) {
-                ReferencePosition position = (ReferencePosition)this.references.elementAt(i);
-                if (this.parennumber <= position.refNumber)
-                    throw ex("parser.parse.2", position.position);
-            }
-            this.references.removeAllElements();
-        }
-        return ret;
-    }
-
-    /*
-    public RegularExpression createRegex(String regex, int options) throws ParseException {
-        Token tok = this.parse(regex, options);
-        return new RegularExpression(regex, tok, this.parennumber, this.hasBackReferences, options);
-    }
-    */
-
-    protected final void setContext(int con) {
-        this.context = con;
-    }
-
-    final int read() {
-        return this.nexttoken;
-    }
-
-    final void next() {
-        if (this.offset >= this.regexlen) {
-            this.chardata = -1;
-            this.nexttoken = T_EOF;
-            return;
-        }
-
-        int ret;
-        int ch = this.regex.charAt(this.offset++);
-        this.chardata = ch;
-
-        if (this.context == S_INBRACKETS) {
-            // In a character class, this.chardata has one character, that is to say,
-            // a pair of surrogates is composed and stored to this.chardata.
-            switch (ch) {
-              case '\\':
-                ret = T_BACKSOLIDUS;
-                if (this.offset >= this.regexlen)
-                    throw ex("parser.next.1", this.offset-1);
-                this.chardata = this.regex.charAt(this.offset++);
-                break;
-
-              case '-':
-                if (this.isSet(RegularExpression.XMLSCHEMA_MODE)
-                    && this.offset < this.regexlen && this.regex.charAt(this.offset) == '[') {
-                    this.offset++;
-                    ret = T_XMLSCHEMA_CC_SUBTRACTION;
-                } else
-                    ret = T_CHAR;
-                break;
-
-              case '[':
-                if (!this.isSet(RegularExpression.XMLSCHEMA_MODE)
-                    && this.offset < this.regexlen && this.regex.charAt(this.offset) == ':') {
-                    this.offset++;
-                    ret = T_POSIX_CHARCLASS_START;
-                    break;
-                } // Through down
-              default:
-                if (REUtil.isHighSurrogate(ch) && this.offset < this.regexlen) {
-                    int low = this.regex.charAt(this.offset);
-                    if (REUtil.isLowSurrogate(low)) {
-                        this.chardata = REUtil.composeFromSurrogates(ch, low);
-                        this.offset ++;
-                    }
-                }
-                ret = T_CHAR;
-            }
-            this.nexttoken = ret;
-            return;
-        }
-
-        switch (ch) {
-          case '|': ret = T_OR;             break;
-          case '*': ret = T_STAR;           break;
-          case '+': ret = T_PLUS;           break;
-          case '?': ret = T_QUESTION;       break;
-          case ')': ret = T_RPAREN;         break;
-          case '.': ret = T_DOT;            break;
-          case '[': ret = T_LBRACKET;       break;
-          case '^': ret = T_CARET;          break;
-          case '$': ret = T_DOLLAR;         break;
-          case '(':
-            ret = T_LPAREN;
-            if (this.offset >= this.regexlen)
-                break;
-            if (this.regex.charAt(this.offset) != '?')
-                break;
-            if (++this.offset >= this.regexlen)
-                throw ex("parser.next.2", this.offset-1);
-            ch = this.regex.charAt(this.offset++);
-            switch (ch) {
-              case ':':  ret = T_LPAREN2;            break;
-              case '=':  ret = T_LOOKAHEAD;          break;
-              case '!':  ret = T_NEGATIVELOOKAHEAD;  break;
-              case '[':  ret = T_SET_OPERATIONS;     break;
-              case '>':  ret = T_INDEPENDENT;        break;
-              case '<':
-                if (this.offset >= this.regexlen)
-                    throw ex("parser.next.2", this.offset-3);
-                ch = this.regex.charAt(this.offset++);
-                if (ch == '=') {
-                    ret = T_LOOKBEHIND;
-                } else if (ch == '!') {
-                    ret = T_NEGATIVELOOKBEHIND;
-                } else
-                    throw ex("parser.next.3", this.offset-3);
-                break;
-              case '#':
-                while (this.offset < this.regexlen) {
-                    ch = this.regex.charAt(this.offset++);
-                    if (ch == ')')  break;
-                }
-                if (ch != ')')
-                    throw ex("parser.next.4", this.offset-1);
-                ret = T_COMMENT;
-                break;
-              default:
-                if (ch == '-' || 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z') {// Options
-                    this.offset --;
-                    ret = T_MODIFIERS;
-                    break;
-                } else if (ch == '(') {         // conditional
-                    ret = T_CONDITION;          // this.offsets points the next of '('.
-                    break;
-                }
-                throw ex("parser.next.2", this.offset-2);
-            }
-            break;
-            
-          case '\\':
-            ret = T_BACKSOLIDUS;
-            if (this.offset >= this.regexlen)
-                throw ex("parser.next.1", this.offset-1);
-            this.chardata = this.regex.charAt(this.offset++);
-            break;
-
-          default:
-            ret = T_CHAR;
-            if (REUtil.isHighSurrogate(this.chardata) && this.offset < this.regexlen)
-                this.chardata = REUtil.composeFromSurrogates(this.chardata,
-                                                             this.regex.charAt(this.offset++));
-        }
-        this.nexttoken = ret;
-    }
-
-    /**
-     * regex ::= term (`|` term)*
-     * term ::= factor+
-     * factor ::= ('^' | '$' | '\A' | '\Z' | '\z' | '\b' | '\B' | '\<' | '\>'
-     *            | atom (('*' | '+' | '?' | minmax ) '?'? )?)
-     *            | '(?=' regex ')'  | '(?!' regex ')'  | '(?&lt;=' regex ')'  | '(?&lt;!' regex ')'
-     * atom ::= char | '.' | range | '(' regex ')' | '(?:' regex ')' | '\' [0-9]
-     *          | '\w' | '\W' | '\d' | '\D' | '\s' | '\S' | category-block 
-     */
-    Token parseRegex() throws ParseException {
-        Token tok = this.parseTerm();
-        Token parent = null;
-        while (this.read() == T_OR) {
-            this.next();                    // '|'
-            if (parent == null) {
-                parent = Token.createUnion();
-                parent.addChild(tok);
-                tok = parent;
-            }
-            tok.addChild(this.parseTerm());
-        }
-        return tok;
-    }
-
-    /**
-     * term ::= factor+
-     */
-    Token parseTerm() throws ParseException {
-        int ch = this.read();
-        if (ch == T_OR || ch == T_RPAREN || ch == T_EOF) {
-            return Token.createEmpty();
-        } else {
-            Token tok = this.parseFactor();
-            Token concat = null;
-            while ((ch = this.read()) != T_OR && ch != T_RPAREN && ch != T_EOF) {
-                if (concat == null) {
-                    concat = Token.createConcat();
-                    concat.addChild(tok);
-                    tok = concat;
-                }
-                concat.addChild(this.parseFactor());
-                //tok = Token.createConcat(tok, this.parseFactor());
-            }
-            return tok;
-        }
-    }
-
-    // ----------------------------------------------------------------
-
-    Token processCaret() throws ParseException {
-        this.next();
-        return Token.token_linebeginning;
-    }
-    Token processDollar() throws ParseException {
-        this.next();
-        return Token.token_lineend;
-    }
-    Token processLookahead() throws ParseException {
-        this.next();
-        Token tok = Token.createLook(Token.LOOKAHEAD, this.parseRegex());
-        if (this.read() != T_RPAREN)  throw ex("parser.factor.1", this.offset-1);
-        this.next();                            // ')'
-        return tok;
-    }
-    Token processNegativelookahead() throws ParseException {
-        this.next();
-        Token tok = Token.createLook(Token.NEGATIVELOOKAHEAD, this.parseRegex());
-        if (this.read() != T_RPAREN)  throw ex("parser.factor.1", this.offset-1);
-        this.next();                            // ')'
-        return tok;
-    }
-    Token processLookbehind() throws ParseException {
-        this.next();
-        Token tok = Token.createLook(Token.LOOKBEHIND, this.parseRegex());
-        if (this.read() != T_RPAREN)  throw ex("parser.factor.1", this.offset-1);
-        this.next();                            // ')'
-        return tok;
-    }
-    Token processNegativelookbehind() throws ParseException {
-        this.next();
-        Token tok = Token.createLook(Token.NEGATIVELOOKBEHIND, this.parseRegex());
-        if (this.read() != T_RPAREN)  throw ex("parser.factor.1", this.offset-1);
-        this.next();                    // ')'
-        return tok;
-    }
-    Token processBacksolidus_A() throws ParseException {
-        this.next();
-        return Token.token_stringbeginning;
-    }
-    Token processBacksolidus_Z() throws ParseException {
-        this.next();
-        return Token.token_stringend2;
-    }
-    Token processBacksolidus_z() throws ParseException {
-        this.next();
-        return Token.token_stringend;
-    }
-    Token processBacksolidus_b() throws ParseException {
-        this.next();
-        return Token.token_wordedge;
-    }
-    Token processBacksolidus_B() throws ParseException {
-        this.next();
-        return Token.token_not_wordedge;
-    }
-    Token processBacksolidus_lt() throws ParseException {
-        this.next();
-        return Token.token_wordbeginning;
-    }
-    Token processBacksolidus_gt() throws ParseException {
-        this.next();
-        return Token.token_wordend;
-    }
-    Token processStar(Token tok) throws ParseException {
-        this.next();
-        if (this.read() == T_QUESTION) {
-            this.next();
-            return Token.createNGClosure(tok);
-        } else
-            return Token.createClosure(tok);
-    }
-    Token processPlus(Token tok) throws ParseException {
-        // X+ -> XX*
-        this.next();
-        if (this.read() == T_QUESTION) {
-            this.next();
-            return Token.createConcat(tok, Token.createNGClosure(tok));
-        } else
-            return Token.createConcat(tok, Token.createClosure(tok));
-    }
-    Token processQuestion(Token tok) throws ParseException {
-        // X? -> X|
-        this.next();
-        Token par = Token.createUnion();
-        if (this.read() == T_QUESTION) {
-            this.next();
-            par.addChild(Token.createEmpty());
-            par.addChild(tok);
-        } else {
-            par.addChild(tok);
-            par.addChild(Token.createEmpty());
-        }
-        return par;
-    }
-    boolean checkQuestion(int off) {
-        return off < this.regexlen && this.regex.charAt(off) == '?';
-    }
-    Token processParen() throws ParseException {
-        this.next();
-        int p = this.parennumber++;
-        Token tok = Token.createParen(this.parseRegex(), p);
-        if (this.read() != T_RPAREN)  throw ex("parser.factor.1", this.offset-1);
-        this.next();                            // Skips ')'
-        return tok;
-    }
-    Token processParen2() throws ParseException {
-        this.next();
-        Token tok = Token.createParen(this.parseRegex(), 0);
-        if (this.read() != T_RPAREN)  throw ex("parser.factor.1", this.offset-1);
-        this.next();                            // Skips ')'
-        return tok;
-    }
-    Token processCondition() throws ParseException {
-                                                // this.offset points the next of '('
-        if (this.offset+1 >= this.regexlen)  throw ex("parser.factor.4", this.offset);
-                                                // Parses a condition.
-        int refno = -1;
-        Token condition = null;
-        int ch = this.regex.charAt(this.offset);
-        if ('1' <= ch && ch <= '9') {
-            refno = ch-'0';
-            this.hasBackReferences = true;
-            if (this.references == null)  this.references = new Vector();
-            this.references.addElement(new ReferencePosition(refno, this.offset));
-            this.offset ++;
-            if (this.regex.charAt(this.offset) != ')')  throw ex("parser.factor.1", this.offset);
-            this.offset ++;
-        } else {
-            if (ch == '?')  this.offset --; // Points '('.
-            this.next();
-            condition = this.parseFactor();
-            switch (condition.type) {
-              case Token.LOOKAHEAD:
-              case Token.NEGATIVELOOKAHEAD:
-              case Token.LOOKBEHIND:
-              case Token.NEGATIVELOOKBEHIND:
-                break;
-              case Token.ANCHOR:
-                if (this.read() != T_RPAREN)  throw ex("parser.factor.1", this.offset-1);
-                break;
-              default:
-                throw ex("parser.factor.5", this.offset);
-            }
-        }
-                                                // Parses yes/no-patterns.
-        this.next();
-        Token yesPattern = this.parseRegex();
-        Token noPattern = null;
-        if (yesPattern.type == Token.UNION) {
-            if (yesPattern.size() != 2)  throw ex("parser.factor.6", this.offset);
-            noPattern = yesPattern.getChild(1);
-            yesPattern = yesPattern.getChild(0);
-        }
-        if (this.read() != T_RPAREN)  throw ex("parser.factor.1", this.offset-1);
-        this.next();
-        return Token.createCondition(refno, condition, yesPattern, noPattern);
-    }
-    Token processModifiers() throws ParseException {
-                                                // this.offset points the next of '?'.
-                                                // modifiers ::= [imsw]* ('-' [imsw]*)? ':'
-        int add = 0, mask = 0, ch = -1;
-        while (this.offset < this.regexlen) {
-            ch = this.regex.charAt(this.offset);
-            int v = REUtil.getOptionValue(ch);
-            if (v == 0)  break;                 // '-' or ':'?
-            add |= v;
-            this.offset ++;
-        }
-        if (this.offset >= this.regexlen)  throw ex("parser.factor.2", this.offset-1);
-        if (ch == '-') {
-            this.offset ++;
-            while (this.offset < this.regexlen) {
-                ch = this.regex.charAt(this.offset);
-                int v = REUtil.getOptionValue(ch);
-                if (v == 0)  break;             // ':'?
-                mask |= v;
-                this.offset ++;
-            }
-            if (this.offset >= this.regexlen)  throw ex("parser.factor.2", this.offset-1);
-        }
-        Token tok;
-        if (ch == ':') {
-            this.offset ++;
-            this.next();
-            tok = Token.createModifierGroup(this.parseRegex(), add, mask);
-            if (this.read() != T_RPAREN)  throw ex("parser.factor.1", this.offset-1);
-            this.next();
-        } else if (ch == ')') {                 // such as (?-i)
-            this.offset ++;
-            this.next();
-            tok = Token.createModifierGroup(this.parseRegex(), add, mask);
-        } else
-            throw ex("parser.factor.3", this.offset);
-
-        return tok;
-    }
-    Token processIndependent() throws ParseException {
-        this.next();
-        Token tok = Token.createLook(Token.INDEPENDENT, this.parseRegex());
-        if (this.read() != T_RPAREN)  throw ex("parser.factor.1", this.offset-1);
-        this.next();                            // Skips ')'
-        return tok;
-    }
-    Token processBacksolidus_c() throws ParseException {
-        int ch2;                                // Must be in 0x0040-0x005f
-        if (this.offset >= this.regexlen
-            || ((ch2 = this.regex.charAt(this.offset++)) & 0xffe0) != 0x0040)
-            throw ex("parser.atom.1", this.offset-1);
-        this.next();
-        return Token.createChar(ch2-0x40);
-    }
-    Token processBacksolidus_C() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processBacksolidus_i() throws ParseException {
-        Token tok = Token.createChar('i');
-        this.next();
-        return tok;
-    }
-    Token processBacksolidus_I() throws ParseException {
-        throw ex("parser.process.1", this.offset);
-    }
-    Token processBacksolidus_g() throws ParseException {
-        this.next();
-        return Token.getGraphemePattern();
-    }
-    Token processBacksolidus_X() throws ParseException {
-        this.next();
-        return Token.getCombiningCharacterSequence();
-    }
-    Token processBackreference() throws ParseException {
-        int refnum = this.chardata-'0';
-        Token tok = Token.createBackReference(refnum);
-        this.hasBackReferences = true;
-        if (this.references == null)  this.references = new Vector();
-        this.references.addElement(new ReferencePosition(refnum, this.offset-2));
-        this.next();
-        return tok;
-    }
-
-    // ----------------------------------------------------------------
-
-    /**
-     * factor ::= ('^' | '$' | '\A' | '\Z' | '\z' | '\b' | '\B' | '\<' | '\>'
-     *            | atom (('*' | '+' | '?' | minmax ) '?'? )?)
-     *            | '(?=' regex ')'  | '(?!' regex ')'  | '(?&lt;=' regex ')'  | '(?&lt;!' regex ')'
-     *            | '(?#' [^)]* ')'
-     * minmax ::= '{' min (',' max?)? '}'
-     * min ::= [0-9]+
-     * max ::= [0-9]+
-     */
-    Token parseFactor() throws ParseException {        
-        int ch = this.read();
-        Token tok;
-        switch (ch) {
-          case T_CARET:         return this.processCaret();
-          case T_DOLLAR:        return this.processDollar();
-          case T_LOOKAHEAD:     return this.processLookahead();
-          case T_NEGATIVELOOKAHEAD: return this.processNegativelookahead();
-          case T_LOOKBEHIND:    return this.processLookbehind();
-          case T_NEGATIVELOOKBEHIND: return this.processNegativelookbehind();
-
-          case T_COMMENT:
-            this.next();
-            return Token.createEmpty();
-
-          case T_BACKSOLIDUS:
-            switch (this.chardata) {
-              case 'A': return this.processBacksolidus_A();
-              case 'Z': return this.processBacksolidus_Z();
-              case 'z': return this.processBacksolidus_z();
-              case 'b': return this.processBacksolidus_b();
-              case 'B': return this.processBacksolidus_B();
-              case '<': return this.processBacksolidus_lt();
-              case '>': return this.processBacksolidus_gt();
-            }
-                                                // through down
-        }
-        tok = this.parseAtom();
-        ch = this.read();
-        switch (ch) {
-          case T_STAR:  return this.processStar(tok);
-          case T_PLUS:  return this.processPlus(tok);
-          case T_QUESTION: return this.processQuestion(tok);
-          case T_CHAR:
-            if (this.chardata == '{') {
-                                                // this.offset -> next of '{'
-                int off = this.offset;
-                int min = 0, max = -1;
-                if (off >= this.regexlen)  break;
-                ch = this.regex.charAt(off++);
-                if (ch != ',' && (ch < '0' || ch > '9'))  break;
-                if (ch != ',') {                // 0-9
-                    min = ch-'0';
-                    while (off < this.regexlen
-                           && (ch = this.regex.charAt(off++)) >= '0' && ch <= '9') {
-                        min = min*10 +ch-'0';
-                        ch = -1;
-                    }
-                    if (ch < 0)  break;
-                }
-                //if (off >= this.regexlen)  break;
-                max = min;
-                if (ch == ',') {
-                    if (off >= this.regexlen
-                        || ((ch = this.regex.charAt(off++)) < '0' || ch > '9')
-                        && ch != '}')
-                        break;
-                    if (ch == '}') {
-                        max = -1;           // {min,}
-                    } else {
-                        max = ch-'0';       // {min,max}
-                        while (off < this.regexlen
-                               && (ch = this.regex.charAt(off++)) >= '0'
-                               && ch <= '9') {
-                            max = max*10 +ch-'0';
-                            ch = -1;
-                        }
-                        if (ch < 0)  break;
-                        //if (min > max)
-                        //    throw new ParseException("parseFactor(): min > max: "+min+", "+max);
-                    }
-                }
-                if (ch != '}')  break;
-                                                // off -> next of '}'
-                if (this.checkQuestion(off)) {
-                    tok = Token.createNGClosure(tok);
-                    this.offset = off+1;
-                } else {
-                    tok = Token.createClosure(tok);
-                    this.offset = off;
-                }
-                tok.setMin(min);
-                tok.setMax(max);
-                //System.err.println("CLOSURE: "+min+", "+max);
-                this.next();
-            }
-        }
-        return tok;
-    }
-
-    /**
-     * atom ::= char | '.' | char-class | '(' regex ')' | '(?:' regex ')' | '\' [0-9]
-     *          | '\w' | '\W' | '\d' | '\D' | '\s' | '\S' | category-block
-     *          | '(?>' regex ')'
-     * char ::= '\\' | '\' [efnrt] | bmp-code | character-1
-     */
-    Token parseAtom() throws ParseException {
-        int ch = this.read();
-        Token tok = null;
-        switch (ch) {
-          case T_LPAREN:        return this.processParen();
-          case T_LPAREN2:       return this.processParen2(); // '(?:'
-          case T_CONDITION:     return this.processCondition(); // '(?('
-          case T_MODIFIERS:     return this.processModifiers(); // (?modifiers ... )
-          case T_INDEPENDENT:   return this.processIndependent();
-          case T_DOT:
-            this.next();                    // Skips '.'
-            tok = Token.token_dot;
-            break;
-
-            /**
-             * char-class ::= '[' ( '^'? range ','?)+ ']'
-             * range ::= '\d' | '\w' | '\s' | category-block | range-char
-             *           | range-char '-' range-char
-             * range-char ::= '\[' | '\]' | '\\' | '\' [,-efnrtv] | bmp-code | character-2
-             * bmp-char ::= '\' 'u' [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F]
-             */
-          case T_LBRACKET:      return this.parseCharacterClass(true);
-          case T_SET_OPERATIONS: return this.parseSetOperations();
-
-          case T_BACKSOLIDUS:
-            switch (this.chardata) {
-              case 'd':  case 'D':
-              case 'w':  case 'W':
-              case 's':  case 'S':
-                tok = this.getTokenForShorthand(this.chardata);
-                this.next();
-                return tok;
-
-              case 'e':  case 'f':  case 'n':  case 'r':
-              case 't':  case 'u':  case 'v':  case 'x':
-                {
-                    int ch2 = this.decodeEscaped();
-                    if (ch2 < 0x10000) {
-                        tok = Token.createChar(ch2);
-                    } else {
-                        tok = Token.createString(REUtil.decomposeToSurrogates(ch2));
-                    }
-                }
-                break;
-
-              case 'c': return this.processBacksolidus_c();
-              case 'C': return this.processBacksolidus_C();
-              case 'i': return this.processBacksolidus_i();
-              case 'I': return this.processBacksolidus_I();
-              case 'g': return this.processBacksolidus_g();
-              case 'X': return this.processBacksolidus_X();
-              case '1':  case '2':  case '3':  case '4':
-              case '5':  case '6':  case '7':  case '8':  case '9':
-                return this.processBackreference();
-
-              case 'P':
-              case 'p':
-                int pstart = this.offset;
-                tok = processBacksolidus_pP(this.chardata);
-                if (tok == null)  throw this.ex("parser.atom.5", pstart);
-                break;
-
-              default:
-                tok = Token.createChar(this.chardata);
-            }
-            this.next();
-            break;
-
-          case T_CHAR:
-            tok = Token.createChar(this.chardata);
-            this.next();
-            break;
-
-          default:
-            throw this.ex("parser.atom.4", this.offset-1);
-        }
-        return tok;
-    }
-
-    protected RangeToken processBacksolidus_pP(int c) throws ParseException {
-        boolean positive = c == 'p';
-        this.next();
-        if (this.read() != T_CHAR)  throw this.ex("parser.atom.2", this.offset-1);
-        RangeToken tok;
-        switch (this.chardata) {
-          case 'L':                             // Letter
-            tok = Token.getRange("L", positive);  break;
-          case 'M':                             // Mark
-            tok = Token.getRange("M", positive);  break;
-          case 'N':                             // Number
-            tok = Token.getRange("N", positive);  break;
-          case 'Z':                             // Separator
-            tok = Token.getRange("Z", positive);  break;
-          case 'C':                             // Other
-            tok = Token.getRange("C", positive);  break;
-          case 'P':                             // Punctuation
-            tok = Token.getRange("P", positive);  break;
-          case 'S':                             // Symbol
-            tok = Token.getRange("S", positive);  break;
-          case '{':
-            // this.offset points the next of '{'.
-            //pstart = this.offset;
-            int namestart = this.offset;
-            int nameend = this.regex.indexOf('}', namestart);
-            if (nameend < 0)  throw this.ex("parser.atom.3", this.offset);
-            this.offset = nameend+1;
-            tok = Token.getRange(this.regex.substring(namestart, nameend), positive);
-            /*
-              if (this.isSet(RegularExpression.IGNORE_CASE))
-              tok = RangeToken.createCaseInsensitiveToken(tok);
-            */
-            break;
-
-          default:
-            throw this.ex("parser.atom.2", this.offset-1);
-        }
-        return tok;
-    }
-
-    int processCIinCharacterClass(RangeToken tok, int c) {
-        return this.decodeEscaped();
-    }
-
-    /**
-     * char-class ::= '[' ( '^'? range ','?)+ ']'
-     * range ::= '\d' | '\w' | '\s' | category-block | range-char
-     *           | range-char '-' range-char
-     * range-char ::= '\[' | '\]' | '\\' | '\' [,-efnrtv] | bmp-code | character-2
-     * bmp-code ::= '\' 'u' [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F]
-     */
-    protected RangeToken parseCharacterClass(boolean useNrange) throws ParseException {
-        this.setContext(S_INBRACKETS);
-        this.next();                            // '['
-        boolean nrange = false;
-        RangeToken base = null;
-        RangeToken tok;
-        if (this.read() == T_CHAR && this.chardata == '^') {
-            nrange = true;
-            this.next();                        // '^'
-            if (useNrange) {
-                tok = Token.createNRange();
-            } else {
-                base = Token.createRange();
-                base.addRange(0, Token.UTF16_MAX);
-                tok = Token.createRange();
-            }
-        } else {
-            tok = Token.createRange();
-        }
-        int type;
-        boolean firstloop = true;
-        while ((type = this.read()) != T_EOF) {
-            if (type == T_CHAR && this.chardata == ']' && !firstloop)
-                break;
-            firstloop = false;
-            int c = this.chardata;
-            boolean end = false;
-            if (type == T_BACKSOLIDUS) {
-                switch (c) {
-                  case 'd':  case 'D':
-                  case 'w':  case 'W':
-                  case 's':  case 'S':
-                    tok.mergeRanges(this.getTokenForShorthand(c));
-                    end = true;
-                    break;
-
-                  case 'i':  case 'I':
-                  case 'c':  case 'C':
-                    c = this.processCIinCharacterClass(tok, c);
-                    if (c < 0)  end = true;
-                    break;
-                    
-                  case 'p':
-                  case 'P':
-                    int pstart = this.offset;
-                    RangeToken tok2 = this.processBacksolidus_pP(c);
-                    if (tok2 == null)  throw this.ex("parser.atom.5", pstart);
-                    tok.mergeRanges(tok2);
-                    end = true;
-                    break;
-
-                  default:
-                    c = this.decodeEscaped();
-                } // \ + c
-            } // backsolidus
-                                                // POSIX Character class such as [:alnum:]
-            else if (type == T_POSIX_CHARCLASS_START) {
-                int nameend = this.regex.indexOf(':', this.offset);
-                if (nameend < 0) throw this.ex("parser.cc.1", this.offset);
-                boolean positive = true;
-                if (this.regex.charAt(this.offset) == '^') {
-                    this.offset ++;
-                    positive = false;
-                }
-                String name = this.regex.substring(this.offset, nameend);
-                RangeToken range = Token.getRange(name, positive);
-                if (range == null)  throw this.ex("parser.cc.3", this.offset);
-                tok.mergeRanges(range);
-                end = true;
-                if (nameend+1 >= this.regexlen || this.regex.charAt(nameend+1) != ']')
-                    throw this.ex("parser.cc.1", nameend);
-                this.offset = nameend+2;
-            }
-            this.next();
-            if (!end) {                         // if not shorthands...
-                if (this.read() != T_CHAR || this.chardata != '-') { // Here is no '-'.
-                    tok.addRange(c, c);
-                } else {
-                    this.next(); // Skips '-'
-                    if ((type = this.read()) == T_EOF)  throw this.ex("parser.cc.2", this.offset);
-                    if (type == T_CHAR && this.chardata == ']') {
-                        tok.addRange(c, c);
-                        tok.addRange('-', '-');
-                    } else {
-                        int rangeend = this.chardata;
-                        if (type == T_BACKSOLIDUS)
-                            rangeend = this.decodeEscaped();
-                        this.next();
-                        tok.addRange(c, rangeend);
-                    }
-                }
-            }
-            if (this.isSet(RegularExpression.SPECIAL_COMMA)
-                && this.read() == T_CHAR && this.chardata == ',')
-                this.next();
-        }
-        if (this.read() == T_EOF)
-            throw this.ex("parser.cc.2", this.offset);
-        if (!useNrange && nrange) {
-            base.subtractRanges(tok);
-            tok = base;
-        }
-        tok.sortRanges();
-        tok.compactRanges();
-        //tok.dumpRanges();
-        /*
-        if (this.isSet(RegularExpression.IGNORE_CASE))
-            tok = RangeToken.createCaseInsensitiveToken(tok);
-        */
-        this.setContext(S_NORMAL);
-        this.next();                    // Skips ']'
-
-        return tok;
-    }
-    private RangeToken parseCharacterClass_old(boolean useNrange) throws ParseException {
-        this.setContext(S_INBRACKETS);
-        this.next();                            // '['
-        boolean nrange = false;
-        RangeToken base = null;
-        RangeToken tok;
-        if (this.read() == T_CHAR && this.chardata == '^') {
-            nrange = true;
-            this.next();                        // '^'
-            if (useNrange) {
-                tok = Token.createNRange();
-            } else {
-                base = Token.createRange();
-                base.addRange(0, Token.UTF16_MAX);
-                tok = Token.createRange();
-            }
-        } else {
-            tok = Token.createRange();
-        }
-        int type;
-        while ((type = this.read()) != T_EOF
-               && !(type == T_CHAR && this.chardata == ']')) {
-            int c = this.chardata;
-            /*
-            if (type == T_CHAR && c == '^') {
-                this.next();
-                type = this.read();
-                c = this.chardata;
-                if (type == T_EOF)  break;
-
-                nrange = !nrange;
-                if (nrange)
-                    tok = Token.createRange();
-                else {
-                    base.subtractRanges(tok);
-                    tok = base;
-                }
-            }
-            */
-            boolean end = false;
-            if (type == T_BACKSOLIDUS) {
-                switch (c) {
-                  case 'd':  case 'D':
-                  case 'w':  case 'W':
-                  case 's':  case 'S':
-                    tok.mergeRanges(this.getTokenForShorthand(c));
-                    end = true;
-                    break;
-
-                  case 'i':  case 'I':
-                  case 'c':  case 'C':
-                    c = this.processCIinCharacterClass(tok, c);
-                    if (c < 0)  end = true;
-                    break;
-                    
-                  case 'p':
-                  case 'P':
-                    boolean positive = c ==  'p';
-                    int pstart = this.offset;
-                    this.next();
-                    if (this.read() != T_CHAR)  throw ex("parser.atom.2", this.offset-1);
-                    RangeToken tok2 = null;
-                    switch (this.chardata) {
-                      case 'L':                 // Letter
-                        tok2 = Token.getRange("L", positive);  break;
-                      case 'M':                 // Mark
-                        tok2 = Token.getRange("M", positive);  break;
-                      case 'N':                 // Number
-                        tok2 = Token.getRange("N", positive);  break;
-                      case 'Z':                 // Separator
-                        tok2 = Token.getRange("Z", positive);  break;
-                      case 'C':                 // Other
-                        tok2 = Token.getRange("C", positive);  break;
-                      case 'P':                 // Punctuation
-                        tok2 = Token.getRange("P", positive);  break;
-                      case 'S':                 // Symbol
-                        tok2 = Token.getRange("S", positive);  break;
-                      case '{':
-                        // this.offset points the next of '{'.
-                        pstart = this.offset;
-                        int namestart = this.offset;
-                        int nameend = this.regex.indexOf('}', namestart);
-                        if (nameend < 0)  throw ex("parser.atom.3", this.offset);
-                        this.offset = nameend+1;
-                        tok2 = Token.getRange(this.regex.substring(namestart, nameend), positive);
-                        break;
-
-                      default:
-                        throw ex("parser.atom.2", this.offset-1);
-                    }
-                    if (tok2 == null)  throw ex("parser.atom.5", pstart);
-                    tok.mergeRanges(tok2);
-                    end = true;
-                    break;
-
-                  default:
-                    c = this.decodeEscaped();
-                } // \ + c
-            } // backsolidus
-                                                // POSIX Character class such as [:alnum:]
-            else if (type == T_POSIX_CHARCLASS_START) {
-                int nameend = this.regex.indexOf(':', this.offset);
-                if (nameend < 0) throw ex("parser.cc.1", this.offset);
-                String name = this.regex.substring(this.offset, nameend);
-                RangeToken range = Token.getRange(name, true);
-                if (range == null)  throw ex("parser.cc.3", this.offset);
-                tok.mergeRanges(range);
-                end = true;
-                if (nameend+1 >= this.regexlen || this.regex.charAt(nameend+1) != ']')
-                    throw ex("parser.cc.1", nameend);
-                this.offset = nameend+2;
-            }
-            this.next();
-            if (!end) {
-                if (this.read() != T_CHAR || this.chardata != '-') { // Here is no '-'.
-                    tok.addRange(c, c);
-                } else {
-                    this.next(); // Skips '-'
-                    if ((type = this.read()) == T_EOF) throw ex("parser.cc.2", this.offset);
-                    int rangeend = this.chardata;
-                    if (type == T_BACKSOLIDUS)
-                        rangeend = this.decodeEscaped();
-                    this.next();
-                    tok.addRange(c, rangeend);
-                }
-            }
-            if (this.read() == T_CHAR && this.chardata == ',')
-                this.next();
-        }
-        if (this.read() == T_EOF)
-            throw ex("parser.cc.2", this.offset);
-        if (!useNrange && nrange) {
-            base.subtractRanges(tok);
-            tok = base;
-        }
-        tok.sortRanges();
-        tok.compactRanges();
-        //tok.dumpRanges();
-        /*
-        if (this.isSet(RegularExpression.IGNORE_CASE))
-            tok = RangeToken.createCaseInsensitiveToken(tok);
-        */
-        this.setContext(S_NORMAL);
-        this.next();                    // Skips ']'
-
-        return tok;
-    }
-
-    /**
-     * '(?[' ... ']' (('-' | '+' | '&') '[' ... ']')? ')'
-     */
-    protected RangeToken parseSetOperations() throws ParseException {
-        RangeToken tok = this.parseCharacterClass(false);
-        int type;
-        while ((type = this.read()) != T_RPAREN) {
-            int ch = this.chardata;
-            if (type == T_CHAR && (ch == '-' || ch == '&')
-                || type == T_PLUS) {
-                this.next();
-                if (this.read() != T_LBRACKET) throw ex("parser.ope.1", this.offset-1);
-                RangeToken t2 = this.parseCharacterClass(false);
-                if (type == T_PLUS)
-                    tok.mergeRanges(t2);
-                else if (ch == '-')
-                    tok.subtractRanges(t2);
-                else if (ch == '&')
-                    tok.intersectRanges(t2);
-                else
-                    throw new RuntimeException("ASSERT");
-            } else {
-                throw ex("parser.ope.2", this.offset-1);
-            }
-        }
-        this.next();
-        return tok;
-    }
-
-    Token getTokenForShorthand(int ch) {
-        Token tok;
-        switch (ch) {
-          case 'd':
-            tok = this.isSet(RegularExpression.USE_UNICODE_CATEGORY)
-                ? Token.getRange("Nd", true) : Token.token_0to9;
-            break;
-          case 'D':
-            tok = this.isSet(RegularExpression.USE_UNICODE_CATEGORY)
-                ? Token.getRange("Nd", false) : Token.token_not_0to9;
-            break;
-          case 'w':
-            tok = this.isSet(RegularExpression.USE_UNICODE_CATEGORY)
-                ? Token.getRange("IsWord", true) : Token.token_wordchars;
-            break;
-          case 'W':
-            tok = this.isSet(RegularExpression.USE_UNICODE_CATEGORY)
-                ? Token.getRange("IsWord", false) : Token.token_not_wordchars;
-            break;
-          case 's':
-            tok = this.isSet(RegularExpression.USE_UNICODE_CATEGORY)
-                ? Token.getRange("IsSpace", true) : Token.token_spaces;
-            break;
-          case 'S':
-            tok = this.isSet(RegularExpression.USE_UNICODE_CATEGORY)
-                ? Token.getRange("IsSpace", false) : Token.token_not_spaces;
-            break;
-
-          default:
-            throw new RuntimeException("Internal Error: shorthands: \\u"+Integer.toString(ch, 16));
-        }
-        return tok;
-    }
-
-    /**
-     */
-    int decodeEscaped() throws ParseException {
-        if (this.read() != T_BACKSOLIDUS)  throw ex("parser.next.1", this.offset-1);
-        int c = this.chardata;
-        switch (c) {
-          case 'e':  c = 0x1b;  break; // ESCAPE U+001B
-          case 'f':  c = '\f';  break; // FORM FEED U+000C
-          case 'n':  c = '\n';  break; // LINE FEED U+000A
-          case 'r':  c = '\r';  break; // CRRIAGE RETURN U+000D
-          case 't':  c = '\t';  break; // HORIZONTAL TABULATION U+0009
-          //case 'v':  c = 0x0b;  break; // VERTICAL TABULATION U+000B
-          case 'x':
-            this.next();
-            if (this.read() != T_CHAR)  throw ex("parser.descape.1", this.offset-1);
-            if (this.chardata == '{') {
-                int v1 = 0;
-                int uv = 0;
-                do {
-                    this.next();
-                    if (this.read() != T_CHAR)  throw ex("parser.descape.1", this.offset-1);
-                    if ((v1 = hexChar(this.chardata)) < 0)
-                        break;
-                    if (uv > uv*16) throw ex("parser.descape.2", this.offset-1);
-                    uv = uv*16+v1;
-                } while (true);
-                if (this.chardata != '}')  throw ex("parser.descape.3", this.offset-1);
-                if (uv > Token.UTF16_MAX)  throw ex("parser.descape.4", this.offset-1);
-                c = uv;
-            } else {
-                int v1 = 0;
-                if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0)
-                    throw ex("parser.descape.1", this.offset-1);
-                int uv = v1;
-                this.next();
-                if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0)
-                    throw ex("parser.descape.1", this.offset-1);
-                uv = uv*16+v1;
-                c = uv;
-            }
-            break;
-
-          case 'u':
-            int v1 = 0;
-            this.next();
-            if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0)
-                throw ex("parser.descape.1", this.offset-1);
-            int uv = v1;
-            this.next();
-            if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0)
-                throw ex("parser.descape.1", this.offset-1);
-            uv = uv*16+v1;
-            this.next();
-            if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0)
-                throw ex("parser.descape.1", this.offset-1);
-            uv = uv*16+v1;
-            this.next();
-            if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0)
-                throw ex("parser.descape.1", this.offset-1);
-            uv = uv*16+v1;
-            c = uv;
-            break;
-
-          case 'v':
-            this.next();
-            if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0)
-                throw ex("parser.descape.1", this.offset-1);
-            uv = v1;
-            this.next();
-            if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0)
-                throw ex("parser.descape.1", this.offset-1);
-            uv = uv*16+v1;
-            this.next();
-            if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0)
-                throw ex("parser.descape.1", this.offset-1);
-            uv = uv*16+v1;
-            this.next();
-            if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0)
-                throw ex("parser.descape.1", this.offset-1);
-            uv = uv*16+v1;
-            this.next();
-            if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0)
-                throw ex("parser.descape.1", this.offset-1);
-            uv = uv*16+v1;
-            this.next();
-            if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0)
-                throw ex("parser.descape.1", this.offset-1);
-            uv = uv*16+v1;
-            if (uv > Token.UTF16_MAX)  throw ex("parser.descappe.4", this.offset-1);
-            c = uv;
-            break;
-          case 'A':
-          case 'Z':
-          case 'z':
-            throw ex("parser.descape.5", this.offset-2);
-          default:
-        }
-        return c;
-    }
-
-    static private final int hexChar(int ch) {
-        if (ch < '0')  return -1;
-        if (ch > 'f')  return -1;
-        if (ch <= '9')  return ch-'0';
-        if (ch < 'A')  return -1;
-        if (ch <= 'F')  return ch-'A'+10;
-        if (ch < 'a')  return -1;
-        return ch-'a'+10;
-    }
-}
diff --git a/src/org/apache/xerces/utils/regex/RegularExpression.java b/src/org/apache/xerces/utils/regex/RegularExpression.java
deleted file mode 100644
index 7246400..0000000
--- a/src/org/apache/xerces/utils/regex/RegularExpression.java
+++ /dev/null
@@ -1,3181 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils.regex;
-
-
-import java.text.CharacterIterator;
-
-/**
- * A regular expression matching engine using Non-deterministic Finite Automaton (NFA).
- * This engine does not conform to the POSIX regular expression.
- *
- * <hr width="50%">
- * <h3>How to use</h3>
- *
- * <dl>
- *   <dt>A. Standard way
- *   <dd>
- * <pre>
- * RegularExpression re = new RegularExpression(<var>regex</var>);
- * if (re.matches(text)) { ... }
- * </pre>
- *
- *   <dt>B. Capturing groups
- *   <dd>
- * <pre>
- * RegularExpression re = new RegularExpression(<var>regex</var>);
- * Match match = new Match();
- * if (re.matches(text, match)) {
- *     ... // You can refer captured texts with methods of the <code>Match</code> class.
- * }
- * </pre>
- *
- * </dl>
- *
- * <h4>Case-insensitive matching</h4>
- * <pre>
- * RegularExpression re = new RegularExpression(<var>regex</var>, "i");
- * if (re.matches(text) >= 0) { ...}
- * </pre>
- *
- * <h4>Options</h4>
- * <p>You can specify options to <a href="#RegularExpression(java.lang.String, java.lang.String)"><code>RegularExpression(</code><var>regex</var><code>, </code><var>options</var><code>)</code></a>
- *    or <a href="#setPattern(java.lang.String, java.lang.String)"><code>setPattern(</code><var>regex</var><code>, </code><var>options</var><code>)</code></a>.
- *    This <var>options</var> parameter consists of the following characters.
- * </p>
- * <dl>
- *   <dt><a name="I_OPTION"><code>"i"</code></a>
- *   <dd>This option indicates case-insensitive matching.
- *   <dt><a name="M_OPTION"><code>"m"</code></a>
- *   <dd class="REGEX"><kbd>^</kbd> and <kbd>$</kbd> consider the EOL characters within the text.
- *   <dt><a name="S_OPTION"><code>"s"</code></a>
- *   <dd class="REGEX"><kbd>.</kbd> matches any one character.
- *   <dt><a name="U_OPTION"><code>"u"</code></a>
- *   <dd class="REGEX">Redefines <Kbd>\d \D \w \W \s \S \b \B \&lt; \></kbd> as becoming to Unicode.
- *   <dt><a name="W_OPTION"><code>"w"</code></a>
- *   <dd class="REGEX">By this option, <kbd>\b \B \&lt; \></kbd> are processed with the method of
- *      'Unicode Regular Expression Guidelines' Revision 4.
- *      When "w" and "u" are specified at the same time,
- *      <kbd>\b \B \&lt; \></kbd> are processed for the "w" option.
- *   <dt><a name="COMMA_OPTION"><code>","</code></a>
- *   <dd>The parser treats a comma in a character class as a range separator.
- *      <kbd class="REGEX">[a,b]</kbd> matches <kbd>a</kbd> or <kbd>,</kbd> or <kbd>b</kbd> without this option.
- *      <kbd class="REGEX">[a,b]</kbd> matches <kbd>a</kbd> or <kbd>b</kbd> with this option.
- *
- *   <dt><a name="X_OPTION"><code>"X"</code></a>
- *   <dd class="REGEX">
- *       By this option, the engine confoms to <a href="http://www.w3.org/TR/2000/WD-xmlschema-2-20000407/#regexs">XML Schema: Regular Expression</a>.
- *       The <code>match()</code> method does not do subsring matching
- *       but entire string matching.
- *
- * </dl>
- * 
- * <hr width="50%">
- * <h3>Syntax</h3>
- * <table border="1" bgcolor="#ddeeff">
- *   <tr>
- *    <td>
- *     <h4>Differences from the Perl 5 regular expression</h4>
- *     <ul>
- *      <li>There is 6-digit hexadecimal character representation  (<kbd>\u005cv</kbd><var>HHHHHH</var>.)
- *      <li>Supports subtraction, union, and intersection operations for character classes.
- *      <li>Not supported: <kbd>\</kbd><var>ooo</var> (Octal character representations),
- *          <Kbd>\G</kbd>, <kbd>\C</kbd>, <kbd>\l</kbd><var>c</var>,
- *          <kbd>\u005cu</kbd><var>c</var>, <kbd>\L</kbd>, <kbd>\U</kbd>,
- *          <kbd>\E</kbd>, <kbd>\Q</kbd>, <kbd>\N{</kbd><var>name</var><kbd>}</kbd>,
- *          <Kbd>(?{<kbd><var>code</var><kbd>})</kbd>, <Kbd>(??{<kbd><var>code</var><kbd>})</kbd>
- *     </ul>
- *    </td>
- *   </tr>
- * </table>
- *
- * <P>Meta characters are `<KBD>. * + ? { [ ( ) | \ ^ $</KBD>'.</P>
- * <ul>
- *   <li>Character
- *     <dl>
- *       <dt class="REGEX"><kbd>.</kbd> (A period)
- *       <dd>Matches any one character except the following characters.
- *       <dd>LINE FEED (U+000A), CARRIAGE RETURN (U+000D),
- *           PARAGRAPH SEPARATOR (U+2029), LINE SEPARATOR (U+2028)
- *       <dd>This expression matches one code point in Unicode. It can match a pair of surrogates.
- *       <dd>When <a href="#S_OPTION">the "s" option</a> is specified,
- *           it matches any character including the above four characters.
- *
- *       <dt class="REGEX"><Kbd>\e \f \n \r \t</kbd>
- *       <dd>Matches ESCAPE (U+001B), FORM FEED (U+000C), LINE FEED (U+000A),
- *           CARRIAGE RETURN (U+000D), HORIZONTAL TABULATION (U+0009)
- *
- *       <dt class="REGEX"><kbd>\c</kbd><var>C</var>
- *       <dd>Matches a control character.
- *           The <var>C</var> must be one of '<kbd>@</kbd>', '<kbd>A</kbd>'-'<kbd>Z</kbd>',
- *           '<kbd>[</kbd>', '<kbd>\u005c</kbd>', '<kbd>]</kbd>', '<kbd>^</kbd>', '<kbd>_</kbd>'.
- *           It matches a control character of which the character code is less than
- *           the character code of the <var>C</var> by 0x0040.
- *       <dd class="REGEX">For example, a <kbd>\cJ</kbd> matches a LINE FEED (U+000A),
- *           and a <kbd>\c[</kbd> matches an ESCAPE (U+001B).
- *
- *       <dt class="REGEX">a non-meta character
- *       <dd>Matches the character.
- *
- *       <dt class="REGEX"><KBD>\</KBD> + a meta character
- *       <dd>Matches the meta character.
- *
- *       <dt class="REGEX"><kbd>\u005cx</kbd><var>HH</var> <kbd>\u005cx{</kbd><var>HHHH</var><kbd>}</kbd>
- *       <dd>Matches a character of which code point is <var>HH</var> (Hexadecimal) in Unicode.
- *           You can write just 2 digits for <kbd>\u005cx</kbd><var>HH</var>, and
- *           variable length digits for <kbd>\u005cx{</kbd><var>HHHH</var><kbd>}</kbd>.
- *
- *       <!--
- *       <dt class="REGEX"><kbd>\u005cu</kbd><var>HHHH</var>
- *       <dd>Matches a character of which code point is <var>HHHH</var> (Hexadecimal) in Unicode.
- *       -->
- *
- *       <dt class="REGEX"><kbd>\u005cv</kbd><var>HHHHHH</var>
- *       <dd>Matches a character of which code point is <var>HHHHHH</var> (Hexadecimal) in Unicode.
- *
- *       <dt class="REGEX"><kbd>\g</kbd>
- *       <dd>Matches a grapheme.
- *       <dd class="REGEX">It is equivalent to <kbd>(?[\p{ASSIGNED}]-[\p{M}\p{C}])?(?:\p{M}|[\x{094D}\x{09CD}\x{0A4D}\x{0ACD}\x{0B3D}\x{0BCD}\x{0C4D}\x{0CCD}\x{0D4D}\x{0E3A}\x{0F84}]\p{L}|[\x{1160}-\x{11A7}]|[\x{11A8}-\x{11FF}]|[\x{FF9E}\x{FF9F}])*</kbd>
- *
- *       <dt class="REGEX"><kbd>\X</kbd>
- *       <dd class="REGEX">Matches a combining character sequence.
- *       It is equivalent to <kbd>(?:\PM\pM*)</kbd>
- *     </dl>
- *   </li>
- *
- *   <li>Character class
- *     <dl>
-+ *       <dt class="REGEX"><kbd>[</kbd><var>R<sub>1</sub></var><var>R<sub>2</sub></var><var>...</var><var>R<sub>n</sub></var><kbd>]</kbd> (without <a href="#COMMA_OPTION">"," option</a>)
-+ *       <dt class="REGEX"><kbd>[</kbd><var>R<sub>1</sub></var><kbd>,</kbd><var>R<sub>2</sub></var><kbd>,</kbd><var>...</var><kbd>,</kbd><var>R<sub>n</sub></var><kbd>]</kbd> (with <a href="#COMMA_OPTION">"," option</a>)
- *       <dd>Positive character class.  It matches a character in ranges.
- *       <dd><var>R<sub>n</sub></var>:
- *       <ul>
- *         <li class="REGEX">A character (including <Kbd>\e \f \n \r \t</kbd> <kbd>\u005cx</kbd><var>HH</var> <kbd>\u005cx{</kbd><var>HHHH</var><kbd>}</kbd> <!--kbd>\u005cu</kbd><var>HHHH</var--> <kbd>\u005cv</kbd><var>HHHHHH</var>)
- *             <p>This range matches the character.
- *         <li class="REGEX"><var>C<sub>1</sub></var><kbd>-</kbd><var>C<sub>2</sub></var>
- *             <p>This range matches a character which has a code point that is >= <var>C<sub>1</sub></var>'s code point and &lt;= <var>C<sub>2</sub></var>'s code point.
-+ *         <li class="REGEX">A POSIX character class: <Kbd>[:alpha:] [:alnum:] [:ascii:] [:cntrl:] [:digit:] [:graph:] [:lower:] [:print:] [:punct:] [:space:] [:upper:] [:xdigit:]</kbd>,
-+ *             and negative POSIX character classes in Perl like <kbd>[:^alpha:]</kbd>
- *             <p>...
- *         <li class="REGEX"><kbd>\d \D \s \S \w \W \p{</kbd><var>name</var><kbd>} \P{</kbd><var>name</var><kbd>}</kbd>
- *             <p>These expressions specifies the same ranges as the following expressions.
- *       </ul>
- *       <p class="REGEX">Enumerated ranges are merged (union operation).
- *          <kbd>[a-ec-z]</kbd> is equivalent to <kbd>[a-z]</kbd>
- *
- *       <dt class="REGEX"><kbd>[^</kbd><var>R<sub>1</sub></var><var>R<sub>2</sub></var><var>...</var><var>R<sub>n</sub></var><kbd>]</kbd> (without a <a href="#COMMA_OPTION">"," option</a>)
- *       <dt class="REGEX"><kbd>[^</kbd><var>R<sub>1</sub></var><kbd>,</kbd><var>R<sub>2</sub></var><kbd>,</kbd><var>...</var><kbd>,</kbd><var>R<sub>n</sub></var><kbd>]</kbd> (with a <a href="#COMMA_OPTION">"," option</a>)
- *       <dd>Negative character class.  It matches a character not in ranges.
- *
- *       <dt class="REGEX"><kbd>(?[</kbd><var>ranges</var><kbd>]</kbd><var>op</var><kbd>[</kbd><var>ranges</var><kbd>]</kbd><var>op</var><kbd>[</kbd><var>ranges</var><kbd>]</kbd> ... <Kbd>)</kbd>
- *       (<var>op</var> is <kbd>-</kbd> or <kbd>+</kbd> or <kbd>&</kbd>.)
- *       <dd>Subtraction or union or intersection for character classes.
- *       <dd class="REGEX">For exmaple, <kbd>(?[A-Z]-[CF])</kbd> is equivalent to <kbd>[A-BD-EG-Z]</kbd>, and <kbd>(?[0x00-0x7f]-[K]&[\p{Lu}])</kbd> is equivalent to <kbd>[A-JL-Z]</kbd>.
- *       <dd>The result of this operations is a <u>positive character class</u>
- *           even if an expression includes any negative character classes.
- *           You have to take care on this in case-insensitive matching.
- *           For instance, <kbd>(?[^b])</kbd> is equivalent to <kbd>[\x00-ac-\x{10ffff}]</kbd>,
- *           which is equivalent to <kbd>[^b]</kbd> in case-sensitive matching.
- *           But, in case-insensitive matching, <kbd>(?[^b])</kbd> matches any character because
- *           it includes '<kbd>B</kbd>' and '<kbd>B</kbd>' matches '<kbd>b</kbd>'
- *           though <kbd>[^b]</kbd> is processed as <kbd>[^Bb]</kbd>.
- *
- *       <dt class="REGEX"><kbd>[</kbd><var>R<sub>1</sub>R<sub>2</sub>...</var><kbd>-[</kbd><var>R<sub>n</sub>R<sub>n+1</sub>...</var><kbd>]]</kbd> (with an <a href="#X_OPTION">"X" option</a>)</dt>
- *       <dd>Character class subtraction for the XML Schema.
- *           You can use this syntax when you specify an <a href="#X_OPTION">"X" option</a>.
- *           
- *       <dt class="REGEX"><kbd>\d</kbd>
- *       <dd class="REGEX">Equivalent to <kbd>[0-9]</kbd>.
- *       <dd>When <a href="#U_OPTION">a "u" option</a> is set, it is equivalent to
- *           <span class="REGEX"><kbd>\p{Nd}</kbd></span>.
- *
- *       <dt class="REGEX"><kbd>\D</kbd>
- *       <dd class="REGEX">Equivalent to <kbd>[^0-9]</kbd>
- *       <dd>When <a href="#U_OPTION">a "u" option</a> is set, it is equivalent to
- *           <span class="REGEX"><kbd>\P{Nd}</kbd></span>.
- *
- *       <dt class="REGEX"><kbd>\s</kbd>
- *       <dd class="REGEX">Equivalent to <kbd>[ \f\n\r\t]</kbd>
- *       <dd>When <a href="#U_OPTION">a "u" option</a> is set, it is equivalent to
- *           <span class="REGEX"><kbd>[ \f\n\r\t\p{Z}]</kbd></span>.
- *
- *       <dt class="REGEX"><kbd>\S</kbd>
- *       <dd class="REGEX">Equivalent to <kbd>[^ \f\n\r\t]</kbd>
- *       <dd>When <a href="#U_OPTION">a "u" option</a> is set, it is equivalent to
- *           <span class="REGEX"><kbd>[^ \f\n\r\t\p{Z}]</kbd></span>.
- *
- *       <dt class="REGEX"><kbd>\w</kbd>
- *       <dd class="REGEX">Equivalent to <kbd>[a-zA-Z0-9_]</kbd>
- *       <dd>When <a href="#U_OPTION">a "u" option</a> is set, it is equivalent to
- *           <span class="REGEX"><kbd>[\p{Lu}\p{Ll}\p{Lo}\p{Nd}_]</kbd></span>.
- *
- *       <dt class="REGEX"><kbd>\W</kbd>
- *       <dd class="REGEX">Equivalent to <kbd>[^a-zA-Z0-9_]</kbd>
- *       <dd>When <a href="#U_OPTION">a "u" option</a> is set, it is equivalent to
- *           <span class="REGEX"><kbd>[^\p{Lu}\p{Ll}\p{Lo}\p{Nd}_]</kbd></span>.
- *
- *       <dt class="REGEX"><kbd>\p{</kbd><var>name</var><kbd>}</kbd>
- *       <dd>Matches one character in the specified General Category (the second field in <a href="ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt"><kbd>UnicodeData.txt</kbd></a>) or the specified <a href="ftp://ftp.unicode.org/Public/UNIDATA/Blocks.txt">Block</a>.
- *       The following names are available:
- *       <dl>
- *         <dt>Unicode General Categories:
- *         <dd><kbd>
- *       L, M, N, Z, C, P, S, Lu, Ll, Lt, Lm, Lo, Mn, Me, Mc, Nd, Nl, No, Zs, Zl, Zp,
- *       Cc, Cf, Cn, Co, Cs, Pd, Ps, Pe, Pc, Po, Sm, Sc, Sk, So,
- *         </kbd>
- *         <dd>(Currently the Cn category includes U+10000-U+10FFFF characters)
- *         <dt>Unicode Blocks:
- *         <dd><kbd>
- *       Basic Latin, Latin-1 Supplement, Latin Extended-A, Latin Extended-B,
- *       IPA Extensions, Spacing Modifier Letters, Combining Diacritical Marks, Greek,
- *       Cyrillic, Armenian, Hebrew, Arabic, Devanagari, Bengali, Gurmukhi, Gujarati,
- *       Oriya, Tamil, Telugu, Kannada, Malayalam, Thai, Lao, Tibetan, Georgian,
- *       Hangul Jamo, Latin Extended Additional, Greek Extended, General Punctuation,
- *       Superscripts and Subscripts, Currency Symbols, Combining Marks for Symbols,
- *       Letterlike Symbols, Number Forms, Arrows, Mathematical Operators,
- *       Miscellaneous Technical, Control Pictures, Optical Character Recognition,
- *       Enclosed Alphanumerics, Box Drawing, Block Elements, Geometric Shapes,
- *       Miscellaneous Symbols, Dingbats, CJK Symbols and Punctuation, Hiragana,
- *       Katakana, Bopomofo, Hangul Compatibility Jamo, Kanbun,
- *       Enclosed CJK Letters and Months, CJK Compatibility, CJK Unified Ideographs,
- *       Hangul Syllables, High Surrogates, High Private Use Surrogates, Low Surrogates,
- *       Private Use, CJK Compatibility Ideographs, Alphabetic Presentation Forms,
- *       Arabic Presentation Forms-A, Combining Half Marks, CJK Compatibility Forms,
- *       Small Form Variants, Arabic Presentation Forms-B, Specials,
- *       Halfwidth and Fullwidth Forms
- *         </kbd>
- *         <dt>Others:
- *         <dd><kbd>ALL</kbd> (Equivalent to <kbd>[\u005cu0000-\u005cv10FFFF]</kbd>)
- *         <dd><kbd>ASSGINED</kbd> (<kbd>\p{ASSIGNED}</kbd> is equivalent to <kbd>\P{Cn}</kbd>)
- *         <dd><kbd>UNASSGINED</kbd>
- *             (<kbd>\p{UNASSIGNED}</kbd> is equivalent to <kbd>\p{Cn}</kbd>)
- *       </dl>
- *
- *       <dt class="REGEX"><kbd>\P{</kbd><var>name</var><kbd>}</kbd>
- *       <dd>Matches one character not in the specified General Category or the specified Block.
- *     </dl>
- *   </li>
- *
- *   <li>Selection and Quantifier
- *     <dl>
- *       <dt class="REGEX"><VAR>X</VAR><kbd>|</kbd><VAR>Y</VAR>
- *       <dd>...
- *
- *       <dt class="REGEX"><VAR>X</VAR><kbd>*</KBD>
- *       <dd>Matches 0 or more <var>X</var>.
- *
- *       <dt class="REGEX"><VAR>X</VAR><kbd>+</KBD>
- *       <dd>Matches 1 or more <var>X</var>.
- *
- *       <dt class="REGEX"><VAR>X</VAR><kbd>?</KBD>
- *       <dd>Matches 0 or 1 <var>X</var>.
- *
- *       <dt class="REGEX"><var>X</var><kbd>{</kbd><var>number</var><kbd>}</kbd>
- *       <dd>Matches <var>number</var> times.
- *
- *       <dt class="REGEX"><var>X</var><kbd>{</kbd><var>min</var><kbd>,}</kbd>
- *       <dd>...
- *
- *       <dt class="REGEX"><var>X</var><kbd>{</kbd><var>min</var><kbd>,</kbd><var>max</var><kbd>}</kbd>
- *       <dd>...
- *
- *       <dt class="REGEX"><VAR>X</VAR><kbd>*?</kbd>
- *       <dt class="REGEX"><VAR>X</VAR><kbd>+?</kbd>
- *       <dt class="REGEX"><VAR>X</VAR><kbd>??</kbd>
- *       <dt class="REGEX"><var>X</var><kbd>{</kbd><var>min</var><kbd>,}?</kbd>
- *       <dt class="REGEX"><var>X</var><kbd>{</kbd><var>min</var><kbd>,</kbd><var>max</var><kbd>}?</kbd>
- *       <dd>Non-greedy matching.
- *     </dl>
- *   </li>
- *
- *   <li>Grouping, Capturing, and Back-reference
- *     <dl>
- *       <dt class="REGEX"><KBD>(?:</kbd><VAR>X</VAR><kbd>)</KBD>
- *       <dd>Grouping. "<KBD>foo+</KBD>" matches "<KBD>foo</KBD>" or "<KBD>foooo</KBD>".
- *       If you want it matches "<KBD>foofoo</KBD>" or "<KBD>foofoofoo</KBD>",
- *       you have to write "<KBD>(?:foo)+</KBD>".
- *
- *       <dt class="REGEX"><KBD>(</kbd><VAR>X</VAR><kbd>)</KBD>
- *       <dd>Grouping with capturing.
- * It make a group and applications can know
- * where in target text a group matched with methods of a <code>Match</code> instance
- * after <code><a href="#matches(java.lang.String, org.apache.xerces.utils.regex.Match)">matches(String,Match)</a></code>.
- * The 0th group means whole of this regular expression.
- * The <VAR>N</VAR>th gorup is the inside of the <VAR>N</VAR>th left parenthesis.
- * 
- *   <p>For instance, a regular expression is
- *   "<FONT color=blue><KBD> *([^&lt;:]*) +&lt;([^&gt;]*)&gt; *</KBD></FONT>"
- *   and target text is
- *   "<FONT color=red><KBD>From: TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;</KBD></FONT>":
- *   <ul>
- *     <li><code>Match.getCapturedText(0)</code>:
- *     "<FONT color=red><KBD> TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;</KBD></FONT>"
- *     <li><code>Match.getCapturedText(1)</code>: "<FONT color=red><KBD>TAMURA Kent</KBD></FONT>"
- *     <li><code>Match.getCapturedText(2)</code>: "<FONT color=red><KBD>kent@trl.ibm.co.jp</KBD></FONT>"
- *   </ul>
- *
- *       <dt class="REGEX"><kbd>\1 \2 \3 \4 \5 \6 \7 \8 \9</kbd>
- *       <dd>
- *
- *       <dt class="REGEX"><kbd>(?></kbd><var>X</var><kbd>)</kbd>
- *       <dd>Independent expression group. ................
- *
- *       <dt class="REGEX"><kbd>(?</kbd><var>options</var><kbd>:</kbd><var>X</var><kbd>)</kbd>
- *       <dt class="REGEX"><kbd>(?</kbd><var>options</var><kbd>-</kbd><var>options2</var><kbd>:</kbd><var>X</var><kbd>)</kbd>
- *       <dd>............................
- *       <dd>The <var>options</var> or the <var>options2</var> consists of 'i' 'm' 's' 'w'.
- *           Note that it can not contain 'u'.
- *
- *       <dt class="REGEX"><kbd>(?</kbd><var>options</var><kbd>)</kbd>
- *       <dt class="REGEX"><kbd>(?</kbd><var>options</var><kbd>-</kbd><var>options2</var><kbd>)</kbd>
- *       <dd>......
- *       <dd>These expressions must be at the beginning of a group.
- *     </dl>
- *   </li>
- *
- *   <li>Anchor
- *     <dl>
- *       <dt class="REGEX"><kbd>\A</kbd>
- *       <dd>Matches the beginnig of the text.
- *
- *       <dt class="REGEX"><kbd>\Z</kbd>
- *       <dd>Matches the end of the text, or before an EOL character at the end of the text,
- *           or CARRIAGE RETURN + LINE FEED at the end of the text.
- *
- *       <dt class="REGEX"><kbd>\z</kbd>
- *       <dd>Matches the end of the text.
- *
- *       <dt class="REGEX"><kbd>^</kbd>
- *       <dd>Matches the beginning of the text.  It is equivalent to <span class="REGEX"><Kbd>\A</kbd></span>.
- *       <dd>When <a href="#M_OPTION">a "m" option</a> is set,
- *           it matches the beginning of the text, or after one of EOL characters (
- *           LINE FEED (U+000A), CARRIAGE RETURN (U+000D), LINE SEPARATOR (U+2028),
- *           PARAGRAPH SEPARATOR (U+2029).)
- *
- *       <dt class="REGEX"><kbd>$</kbd>
- *       <dd>Matches the end of the text, or before an EOL character at the end of the text,
- *           or CARRIAGE RETURN + LINE FEED at the end of the text.
- *       <dd>When <a href="#M_OPTION">a "m" option</a> is set,
- *           it matches the end of the text, or before an EOL character.
- *
- *       <dt class="REGEX"><kbd>\b</kbd>
- *       <dd>Matches word boundary.
- *           (See <a href="#W_OPTION">a "w" option</a>)
- *
- *       <dt class="REGEX"><kbd>\B</kbd>
- *       <dd>Matches non word boundary.
- *           (See <a href="#W_OPTION">a "w" option</a>)
- *
- *       <dt class="REGEX"><kbd>\&lt;</kbd>
- *       <dd>Matches the beginning of a word.
- *           (See <a href="#W_OPTION">a "w" option</a>)
- *
- *       <dt class="REGEX"><kbd>\&gt;</kbd>
- *       <dd>Matches the end of a word.
- *           (See <a href="#W_OPTION">a "w" option</a>)
- *     </dl>
- *   </li>
- *   <li>Lookahead and lookbehind
- *     <dl>
- *       <dt class="REGEX"><kbd>(?=</kbd><var>X</var><kbd>)</kbd>
- *       <dd>Lookahead.
- *
- *       <dt class="REGEX"><kbd>(?!</kbd><var>X</var><kbd>)</kbd>
- *       <dd>Negative lookahead.
- *
- *       <dt class="REGEX"><kbd>(?&lt;=</kbd><var>X</var><kbd>)</kbd>
- *       <dd>Lookbehind.
- *       <dd>(Note for text capturing......)
- *
- *       <dt class="REGEX"><kbd>(?&lt;!</kbd><var>X</var><kbd>)</kbd>
- *       <dd>Negative lookbehind.
- *     </dl>
- *   </li>
- *
- *   <li>Misc.
- *     <dl>
- *       <dt class="REGEX"><kbd>(?(</Kbd><var>condition</var><Kbd>)</kbd><var>yes-pattern</var><kbd>|</kbd><var>no-pattern</var><kbd>)</kbd>,
- *       <dt class="REGEX"><kbd>(?(</kbd><var>condition</var><kbd>)</kbd><var>yes-pattern</var><kbd>)</kbd>
- *       <dd>......
- *       <dt class="REGEX"><kbd>(?#</kbd><var>comment</var><kbd>)</kbd>
- *       <dd>Comment.  A comment string consists of characters except '<kbd>)</kbd>'.
- *           You can not write comments in character classes and before quantifiers.
- *     </dl>
- *   </li>
- * </ul>
- *
- *
- * <hr width="50%">
- * <h3>BNF for the regular expression</h3>
- * <pre>
- * regex ::= ('(?' options ')')? term ('|' term)*
- * term ::= factor+
- * factor ::= anchors | atom (('*' | '+' | '?' | minmax ) '?'? )?
- *            | '(?#' [^)]* ')'
- * minmax ::= '{' ([0-9]+ | [0-9]+ ',' | ',' [0-9]+ | [0-9]+ ',' [0-9]+) '}'
- * atom ::= char | '.' | char-class | '(' regex ')' | '(?:' regex ')' | '\' [0-9]
- *          | '\w' | '\W' | '\d' | '\D' | '\s' | '\S' | category-block | '\X'
- *          | '(?>' regex ')' | '(?' options ':' regex ')'
- *          | '(?' ('(' [0-9] ')' | '(' anchors ')' | looks) term ('|' term)? ')'
- * options ::= [imsw]* ('-' [imsw]+)?
- * anchors ::= '^' | '$' | '\A' | '\Z' | '\z' | '\b' | '\B' | '\&lt;' | '\>'
- * looks ::= '(?=' regex ')'  | '(?!' regex ')'
- *           | '(?&lt;=' regex ')' | '(?&lt;!' regex ')'
- * char ::= '\\' | '\' [efnrtv] | '\c' [@-_] | code-point | character-1
- * category-block ::= '\' [pP] category-symbol-1
- *                    | ('\p{' | '\P{') (category-symbol | block-name
- *                                       | other-properties) '}'
- * category-symbol-1 ::= 'L' | 'M' | 'N' | 'Z' | 'C' | 'P' | 'S'
- * category-symbol ::= category-symbol-1 | 'Lu' | 'Ll' | 'Lt' | 'Lm' | Lo'
- *                     | 'Mn' | 'Me' | 'Mc' | 'Nd' | 'Nl' | 'No'
- *                     | 'Zs' | 'Zl' | 'Zp' | 'Cc' | 'Cf' | 'Cn' | 'Co' | 'Cs'
- *                     | 'Pd' | 'Ps' | 'Pe' | 'Pc' | 'Po'
- *                     | 'Sm' | 'Sc' | 'Sk' | 'So'
- * block-name ::= (See above)
- * other-properties ::= 'ALL' | 'ASSIGNED' | 'UNASSIGNED'
- * character-1 ::= (any character except meta-characters)
- *
- * char-class ::= '[' ranges ']'
- *                | '(?[' ranges ']' ([-+&] '[' ranges ']')? ')'
- * ranges ::= '^'? (range <a href="#COMMA_OPTION">','?</a>)+
- * range ::= '\d' | '\w' | '\s' | '\D' | '\W' | '\S' | category-block
- *           | range-char | range-char '-' range-char
- * range-char ::= '\[' | '\]' | '\\' | '\' [,-efnrtv] | code-point | character-2
- * code-point ::= '\x' hex-char hex-char
- *                | '\x{' hex-char+ '}'
- * <!--               | '\u005cu' hex-char hex-char hex-char hex-char
- * -->               | '\v' hex-char hex-char hex-char hex-char hex-char hex-char
- * hex-char ::= [0-9a-fA-F]
- * character-2 ::= (any character except \[]-,)
- * </pre>
- *
- * <hr width="50%">
- * <h3>TODO</h3>
- * <ul>
- *   <li><a href="http://www.unicode.org/unicode/reports/tr18/">Unicode Regular Expression Guidelines</a>
- *     <ul>
- *       <li>2.4 Canonical Equivalents
- *       <li>Level 3
- *     </ul>
- *   <li>Parsing performance
- * </ul>
- *
- * <hr width="50%">
- *
- * @author TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;
- */
-public class RegularExpression implements java.io.Serializable {
-    static final boolean DEBUG = false;
-
-    /**
-     * Compiles a token tree into an operation flow.
-     */
-    private synchronized void compile(Token tok) {
-        if (this.operations != null)
-            return;
-        this.numberOfClosures = 0;
-        this.operations = this.compile(tok, null, false);
-    }
-
-    /**
-     * Converts a token to an operation.
-     */
-    private Op compile(Token tok, Op next, boolean reverse) {
-        Op ret;
-        switch (tok.type) {
-        case Token.DOT:
-            ret = Op.createDot();
-            ret.next = next;
-            break;
-
-        case Token.CHAR:
-            ret = Op.createChar(tok.getChar());
-            ret.next = next;
-            break;
-
-        case Token.ANCHOR:
-            ret = Op.createAnchor(tok.getChar());
-            ret.next = next;
-            break;
-
-        case Token.RANGE:
-        case Token.NRANGE:
-            ret = Op.createRange(tok);
-            ret.next = next;
-            break;
-
-        case Token.CONCAT:
-            ret = next;
-            if (!reverse) {
-                for (int i = tok.size()-1;  i >= 0;  i --) {
-                    ret = compile(tok.getChild(i), ret, false);
-                }
-            } else {
-                for (int i = 0;  i < tok.size();  i ++) {
-                    ret = compile(tok.getChild(i), ret, true);
-                }
-            }
-            break;
-
-        case Token.UNION:
-            Op.UnionOp uni = Op.createUnion(tok.size());
-            for (int i = 0;  i < tok.size();  i ++) {
-                uni.addElement(compile(tok.getChild(i), next, reverse));
-            }
-            ret = uni;                          // ret.next is null.
-            break;
-
-        case Token.CLOSURE:
-        case Token.NONGREEDYCLOSURE:
-            Token child = tok.getChild(0);
-            int min = tok.getMin();
-            int max = tok.getMax();
-            if (min >= 0 && min == max) { // {n}
-                ret = next;
-                for (int i = 0; i < min;  i ++) {
-                    ret = compile(child, ret, reverse);
-                }
-                break;
-            }
-            if (min > 0 && max > 0)
-                max -= min;
-            if (max > 0) {
-                // X{2,6} -> XX(X(X(XX?)?)?)?
-                ret = next;
-                for (int i = 0;  i < max;  i ++) {
-                    Op.ChildOp q = Op.createQuestion(tok.type == Token.NONGREEDYCLOSURE);
-                    q.next = next;
-                    q.setChild(compile(child, ret, reverse));
-                    ret = q;
-                }
-            } else {
-                Op.ChildOp op;
-                if (tok.type == Token.NONGREEDYCLOSURE) {
-                    op = Op.createNonGreedyClosure();
-                } else {                        // Token.CLOSURE
-                    if (child.getMinLength() == 0)
-                        op = Op.createClosure(this.numberOfClosures++);
-                    else
-                        op = Op.createClosure(-1);
-                }
-                op.next = next;
-                op.setChild(compile(child, op, reverse));
-                ret = op;
-            }
-            if (min > 0) {
-                for (int i = 0;  i < min;  i ++) {
-                    ret = compile(child, ret, reverse);
-                }
-            }
-            break;
-
-        case Token.EMPTY:
-            ret = next;
-            break;
-
-        case Token.STRING:
-            ret = Op.createString(tok.getString());
-            ret.next = next;
-            break;
-
-        case Token.BACKREFERENCE:
-            ret = Op.createBackReference(tok.getReferenceNumber());
-            ret.next = next;
-            break;
-
-        case Token.PAREN:
-            if (tok.getParenNumber() == 0) {
-                ret = compile(tok.getChild(0), next, reverse);
-            } else if (reverse) {
-                next = Op.createCapture(tok.getParenNumber(), next);
-                next = compile(tok.getChild(0), next, reverse);
-                ret = Op.createCapture(-tok.getParenNumber(), next);
-            } else {
-                next = Op.createCapture(-tok.getParenNumber(), next);
-                next = compile(tok.getChild(0), next, reverse);
-                ret = Op.createCapture(tok.getParenNumber(), next);
-            }
-            break;
-
-        case Token.LOOKAHEAD:
-            ret = Op.createLook(Op.LOOKAHEAD, next, compile(tok.getChild(0), null, false));
-            break;
-        case Token.NEGATIVELOOKAHEAD:
-            ret = Op.createLook(Op.NEGATIVELOOKAHEAD, next, compile(tok.getChild(0), null, false));
-            break;
-        case Token.LOOKBEHIND:
-            ret = Op.createLook(Op.LOOKBEHIND, next, compile(tok.getChild(0), null, true));
-            break;
-        case Token.NEGATIVELOOKBEHIND:
-            ret = Op.createLook(Op.NEGATIVELOOKBEHIND, next, compile(tok.getChild(0), null, true));
-            break;
-
-        case Token.INDEPENDENT:
-            ret = Op.createIndependent(next, compile(tok.getChild(0), null, reverse));
-            break;
-
-        case Token.MODIFIERGROUP:
-            ret = Op.createModifier(next, compile(tok.getChild(0), null, reverse),
-                                    ((Token.ModifierToken)tok).getOptions(),
-                                    ((Token.ModifierToken)tok).getOptionsMask());
-            break;
-
-        case Token.CONDITION:
-            Token.ConditionToken ctok = (Token.ConditionToken)tok;
-            int ref = ctok.refNumber;
-            Op condition = ctok.condition == null ? null : compile(ctok.condition, null, reverse);
-            Op yes = compile(ctok.yes, next, reverse);
-            Op no = ctok.no == null ? null : compile(ctok.no, next, reverse);
-            ret = Op.createCondition(next, ref, condition, yes, no);
-            break;
-
-        default:
-            throw new RuntimeException("Unknown token type: "+tok.type);
-        } // switch (tok.type)
-        return ret;
-    }
-
-
-//Public
-
-    /**
-     * Checks whether the <var>target</var> text <strong>contains</strong> this pattern or not.
-     *
-     * @return true if the target is matched to this regular expression.
-     */
-    public boolean matches(char[]  target) {
-        return this.matches(target, 0,  target .length , (Match)null);
-    }
-
-    /**
-     * Checks whether the <var>target</var> text <strong>contains</strong> this pattern
-     * in specified range or not.
-     *
-     * @param start Start offset of the range.
-     * @param end  End offset +1 of the range.
-     * @return true if the target is matched to this regular expression.
-     */
-    public boolean matches(char[]  target, int start, int end) {
-        return this.matches(target, start, end, (Match)null);
-    }
-
-    /**
-     * Checks whether the <var>target</var> text <strong>contains</strong> this pattern or not.
-     *
-     * @param match A Match instance for storing matching result.
-     * @return Offset of the start position in <VAR>target</VAR>; or -1 if not match.
-     */
-    public boolean matches(char[]  target, Match match) {
-        return this.matches(target, 0,  target .length , match);
-    }
-
-
-    /**
-     * Checks whether the <var>target</var> text <strong>contains</strong> this pattern
-     * in specified range or not.
-     *
-     * @param start Start offset of the range.
-     * @param end  End offset +1 of the range.
-     * @param match A Match instance for storing matching result.
-     * @return Offset of the start position in <VAR>target</VAR>; or -1 if not match.
-     */
-    public boolean matches(char[]  target, int start, int end, Match match) {
-
-        synchronized (this) {
-            if (this.operations == null)
-                this.prepare();
-            if (this.context == null)
-                this.context = new Context();
-        }
-        Context con = null;
-        synchronized (this.context) {
-            con = this.context.inuse ? new Context() : this.context;
-            con.reset(target, start, end, this.numberOfClosures);
-        }
-        if (match != null) {
-            match.setNumberOfGroups(this.nofparen);
-            match.setSource(target);
-        } else if (this.hasBackReferences) {
-            match = new Match();
-            match.setNumberOfGroups(this.nofparen);
-            // Need not to call setSource() because
-            // a caller can not access this match instance.
-        }
-        con.match = match;
-
-        if (this.isSet(this.options, XMLSCHEMA_MODE)) {
-            int matchEnd = this. matchCharArray (con, this.operations, con.start, 1, this.options);
-            //System.err.println("DEBUG: matchEnd="+matchEnd);
-            if (matchEnd == con.limit) {
-                if (con.match != null) {
-                    con.match.setBeginning(0, con.start);
-                    con.match.setEnd(0, matchEnd);
-                }
-                con.inuse = false;
-                return true;
-            }
-            return false;
-        }
-
-        /*
-         * The pattern has only fixed string.
-         * The engine uses Boyer-Moore.
-         */
-        if (this.fixedStringOnly) {
-            //System.err.println("DEBUG: fixed-only: "+this.fixedString);
-            int o = this.fixedStringTable.matches(target, con.start, con.limit);
-            if (o >= 0) {
-                if (con.match != null) {
-                    con.match.setBeginning(0, o);
-                    con.match.setEnd(0, o+this.fixedString.length());
-                }
-                con.inuse = false;
-                return true;
-            }
-            con.inuse = false;
-            return false;
-        }
-
-        /*
-         * The pattern contains a fixed string.
-         * The engine checks with Boyer-Moore whether the text contains the fixed string or not.
-         * If not, it return with false.
-         */
-        if (this.fixedString != null) {
-            int o = this.fixedStringTable.matches(target, con.start, con.limit);
-            if (o < 0) {
-                //System.err.println("Non-match in fixed-string search.");
-                con.inuse = false;
-                return false;
-            }
-        }
-
-        int limit = con.limit-this.minlength;
-        int matchStart;
-        int matchEnd = -1;
-
-        /*
-         * Checks whether the expression starts with ".*".
-         */
-        if (this.operations != null
-            && this.operations.type == Op.CLOSURE && this.operations.getChild().type == Op.DOT) {
-            if (isSet(this.options, SINGLE_LINE)) {
-                matchStart = con.start;
-                matchEnd = this. matchCharArray (con, this.operations, con.start, 1, this.options);
-            } else {
-                boolean previousIsEOL = true;
-                for (matchStart = con.start;  matchStart <= limit;  matchStart ++) {
-                    int ch =  target [  matchStart ] ;
-                    if (isEOLChar(ch)) {
-                        previousIsEOL = true;
-                    } else {
-                        if (previousIsEOL) {
-                            if (0 <= (matchEnd = this. matchCharArray (con, this.operations,
-                                                                       matchStart, 1, this.options)))
-                                break;
-                        }
-                        previousIsEOL = false;
-                    }
-                }
-            }
-        }
-
-        /*
-         * Optimization against the first character.
-         */
-        else if (this.firstChar != null) {
-            //System.err.println("DEBUG: with firstchar-matching: "+this.firstChar);
-            RangeToken range = this.firstChar;
-            if (this.isSet(this.options, IGNORE_CASE)) {
-                range = this.firstChar.getCaseInsensitiveToken();
-                for (matchStart = con.start;  matchStart <= limit;  matchStart ++) {
-                    int ch =  target [  matchStart ] ;
-                    if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) {
-                        ch = REUtil.composeFromSurrogates(ch,  target [  matchStart+1 ] );
-                        if (!range.match(ch))  continue;
-                    } else {
-                        if (!range.match(ch)) {
-                            char ch1 = Character.toUpperCase((char)ch);
-                            if (!range.match(ch1))
-                                if (!range.match(Character.toLowerCase(ch1)))
-                                    continue;
-                        }
-                    }
-                    if (0 <= (matchEnd = this. matchCharArray (con, this.operations,
-                                                               matchStart, 1, this.options)))
-                        break;
-                }
-            } else {
-                for (matchStart = con.start;  matchStart <= limit;  matchStart ++) {
-                    int ch =  target [  matchStart ] ;
-                    if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit)
-                        ch = REUtil.composeFromSurrogates(ch,  target [  matchStart+1 ] );
-                    if (!range.match(ch))  continue;
-                    if (0 <= (matchEnd = this. matchCharArray (con, this.operations,
-                                                               matchStart, 1, this.options)))
-                        break;
-                }
-            }
-        }
-
-        /*
-         * Straightforward matching.
-         */
-        else {
-            for (matchStart = con.start;  matchStart <= limit;  matchStart ++) {
-                if (0 <= (matchEnd = this. matchCharArray (con, this.operations, matchStart, 1, this.options)))
-                    break;
-            }
-        }
-
-        if (matchEnd >= 0) {
-            if (con.match != null) {
-                con.match.setBeginning(0, matchStart);
-                con.match.setEnd(0, matchEnd);
-            }
-            con.inuse = false;
-            return true;
-        } else {
-            con.inuse = false;
-            return false;
-        }
-    }
-
-/**
- * @return -1 when not match; offset of the end of matched string when match.
- */
-    private int matchCharArray (Context con, Op op, int offset, int dx, int opts) {
-
-        char[] target = con.charTarget;
-
-
-        while (true) {
-            if (op == null)
-                return offset;
-            if (offset > con.limit || offset < con.start)
-                return -1;
-            switch (op.type) {
-            case Op.CHAR:
-                if (isSet(opts, IGNORE_CASE)) {
-                    int ch = op.getData();
-                    if (dx > 0) {
-                        if (offset >= con.limit || !matchIgnoreCase(ch,  target [  offset ] ))
-                            return -1;
-                        offset ++;
-                    } else {
-                        int o1 = offset-1;
-                        if (o1 >= con.limit || o1 < 0 || !matchIgnoreCase(ch,  target [  o1 ] ))
-                            return -1;
-                        offset = o1;
-                    }
-                } else {
-                    int ch = op.getData();
-                    if (dx > 0) {
-                        if (offset >= con.limit || ch !=  target [  offset ] )
-                            return -1;
-                        offset ++;
-                    } else {
-                        int o1 = offset-1;
-                        if (o1 >= con.limit || o1 < 0 || ch !=  target [  o1 ] )
-                            return -1;
-                        offset = o1;
-                    }
-                }
-                op = op.next;
-                break;
-
-            case Op.DOT:
-                if (dx > 0) {
-                    if (offset >= con.limit)
-                        return -1;
-                    int ch =  target [  offset ] ;
-                    if (isSet(opts, SINGLE_LINE)) {
-                        if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit)
-                            offset ++;
-                    } else {
-                        if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit)
-                            ch = REUtil.composeFromSurrogates(ch,  target [  ++offset ] );
-                        if (isEOLChar(ch))
-                            return -1;
-                    }
-                    offset ++;
-                } else {
-                    int o1 = offset-1;
-                    if (o1 >= con.limit || o1 < 0)
-                        return -1;
-                    int ch =  target [  o1 ] ;
-                    if (isSet(opts, SINGLE_LINE)) {
-                        if (REUtil.isLowSurrogate(ch) && o1-1 >= 0)
-                            o1 --;
-                    } else {
-                        if (REUtil.isLowSurrogate(ch) && o1-1 >= 0)
-                            ch = REUtil.composeFromSurrogates( target [  --o1 ] , ch);
-                        if (!isEOLChar(ch))
-                            return -1;
-                    }
-                    offset = o1;
-                }
-                op = op.next;
-                break;
-
-            case Op.RANGE:
-            case Op.NRANGE:
-                if (dx > 0) {
-                    if (offset >= con.limit)
-                        return -1;
-                    int ch =  target [  offset ] ;
-                    if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit)
-                        ch = REUtil.composeFromSurrogates(ch,  target [  ++offset ] );
-                    RangeToken tok = op.getToken();
-                    if (isSet(opts, IGNORE_CASE)) {
-                        tok = tok.getCaseInsensitiveToken();
-                        if (!tok.match(ch)) {
-                            if (ch >= 0x10000)  return -1;
-                            char uch;
-                            if (!tok.match(uch = Character.toUpperCase((char)ch))
-                                && !tok.match(Character.toLowerCase(uch)))
-                                return -1;
-                        }
-                    } else {
-                        if (!tok.match(ch))  return -1;
-                    }
-                    offset ++;
-                } else {
-                    int o1 = offset-1;
-                    if (o1 >= con.limit || o1 < 0)
-                        return -1;
-                    int ch =  target [  o1 ] ;
-                    if (REUtil.isLowSurrogate(ch) && o1-1 >= 0)
-                        ch = REUtil.composeFromSurrogates( target [  --o1 ] , ch);
-                    RangeToken tok = op.getToken();
-                    if (isSet(opts, IGNORE_CASE)) {
-                        tok = tok.getCaseInsensitiveToken();
-                        if (!tok.match(ch)) {
-                            if (ch >= 0x10000)  return -1;
-                            char uch;
-                            if (!tok.match(uch = Character.toUpperCase((char)ch))
-                                && !tok.match(Character.toLowerCase(uch)))
-                                return -1;
-                        }
-                    } else {
-                        if (!tok.match(ch))  return -1;
-                    }
-                    offset = o1;
-                }
-                op = op.next;
-                break;
-
-            case Op.ANCHOR:
-                boolean go = false;
-                switch (op.getData()) {
-                case '^':
-                    if (isSet(opts, MULTIPLE_LINES)) {
-                        if (!(offset == con.start
-                              || offset > con.start && isEOLChar( target [  offset-1 ] )))
-                            return -1;
-                    } else {
-                        if (offset != con.start)
-                            return -1;
-                    }
-                    break;
-
-                case '@':                         // Internal use only.
-                    // The @ always matches line beginnings.
-                    if (!(offset == con.start
-                          || offset > con.start && isEOLChar( target [  offset-1 ] )))
-                        return -1;
-                    break;
-
-                case '$':
-                    if (isSet(opts, MULTIPLE_LINES)) {
-                        if (!(offset == con.limit
-                              || offset < con.limit && isEOLChar( target [  offset ] )))
-                            return -1;
-                    } else {
-                        if (!(offset == con.limit
-                              || offset+1 == con.limit && isEOLChar( target [  offset ] )
-                              || offset+2 == con.limit &&  target [  offset ]  == CARRIAGE_RETURN
-                              &&  target [  offset+1 ]  == LINE_FEED))
-                            return -1;
-                    }
-                    break;
-
-                case 'A':
-                    if (offset != con.start)  return -1;
-                    break;
-
-                case 'Z':
-                    if (!(offset == con.limit
-                          || offset+1 == con.limit && isEOLChar( target [  offset ] )
-                          || offset+2 == con.limit &&  target [  offset ]  == CARRIAGE_RETURN
-                          &&  target [  offset+1 ]  == LINE_FEED))
-                        return -1;
-                    break;
-
-                case 'z':
-                    if (offset != con.limit)  return -1;
-                    break;
-
-                case 'b':
-                    if (con.length == 0)  return -1;
-                    {
-                        int after = getWordType(target, con.start, con.limit, offset, opts);
-                        if (after == WT_IGNORE)  return -1;
-                        int before = getPreviousWordType(target, con.start, con.limit, offset, opts);
-                        if (after == before)  return -1;
-                    }
-                    break;
-
-                case 'B':
-                    if (con.length == 0)
-                        go = true;
-                    else {
-                        int after = getWordType(target, con.start, con.limit, offset, opts);
-                        go = after == WT_IGNORE
-                             || after == getPreviousWordType(target, con.start, con.limit, offset, opts);
-                    }
-                    if (!go)  return -1;
-                    break;
-
-                case '<':
-                    if (con.length == 0 || offset == con.limit)  return -1;
-                    if (getWordType(target, con.start, con.limit, offset, opts) != WT_LETTER
-                        || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_OTHER)
-                        return -1;
-                    break;
-
-                case '>':
-                    if (con.length == 0 || offset == con.start)  return -1;
-                    if (getWordType(target, con.start, con.limit, offset, opts) != WT_OTHER
-                        || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_LETTER)
-                        return -1;
-                    break;
-                } // switch anchor type
-                op = op.next;
-                break;
-
-            case Op.BACKREFERENCE:
-                {
-                    int refno = op.getData();
-                    if (refno <= 0 || refno >= this.nofparen)
-                        throw new RuntimeException("Internal Error: Reference number must be more than zero: "+refno);
-                    if (con.match.getBeginning(refno) < 0
-                        || con.match.getEnd(refno) < 0)
-                        return -1;                // ********
-                    int o2 = con.match.getBeginning(refno);
-                    int literallen = con.match.getEnd(refno)-o2;
-                    if (!isSet(opts, IGNORE_CASE)) {
-                        if (dx > 0) {
-                            if (!regionMatches(target, offset, con.limit, o2, literallen))
-                                return -1;
-                            offset += literallen;
-                        } else {
-                            if (!regionMatches(target, offset-literallen, con.limit, o2, literallen))
-                                return -1;
-                            offset -= literallen;
-                        }
-                    } else {
-                        if (dx > 0) {
-                            if (!regionMatchesIgnoreCase(target, offset, con.limit, o2, literallen))
-                                return -1;
-                            offset += literallen;
-                        } else {
-                            if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit,
-                                                         o2, literallen))
-                                return -1;
-                            offset -= literallen;
-                        }
-                    }
-                }
-                op = op.next;
-                break;
-            case Op.STRING:
-                {
-                    String literal = op.getString();
-                    int literallen = literal.length();
-                    if (!isSet(opts, IGNORE_CASE)) {
-                        if (dx > 0) {
-                            if (!regionMatches(target, offset, con.limit, literal, literallen))
-                                return -1;
-                            offset += literallen;
-                        } else {
-                            if (!regionMatches(target, offset-literallen, con.limit, literal, literallen))
-                                return -1;
-                            offset -= literallen;
-                        }
-                    } else {
-                        if (dx > 0) {
-                            if (!regionMatchesIgnoreCase(target, offset, con.limit, literal, literallen))
-                                return -1;
-                            offset += literallen;
-                        } else {
-                            if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit,
-                                                         literal, literallen))
-                                return -1;
-                            offset -= literallen;
-                        }
-                    }
-                }
-                op = op.next;
-                break;
-
-            case Op.CLOSURE:
-                {
-                    /*
-                     * Saves current position to avoid
-                     * zero-width repeats.
-                     */
-                    int id = op.getData();
-                    if (id >= 0) {
-                        int previousOffset = con.offsets[id];
-                        if (previousOffset < 0 || previousOffset != offset) {
-                            con.offsets[id] = offset;
-                        } else {
-                            con.offsets[id] = -1;
-                            op = op.next;
-                            break;
-                        }
-                    }
-
-                    int ret = this. matchCharArray (con, op.getChild(), offset, dx, opts);
-                    if (id >= 0)  con.offsets[id] = -1;
-                    if (ret >= 0)  return ret;
-                    op = op.next;
-                }
-                break;
-
-            case Op.QUESTION:
-                {
-                    int ret = this. matchCharArray (con, op.getChild(), offset, dx, opts);
-                    if (ret >= 0)  return ret;
-                    op = op.next;
-                }
-                break;
-
-            case Op.NONGREEDYCLOSURE:
-            case Op.NONGREEDYQUESTION:
-                {
-                    int ret = this. matchCharArray (con, op.next, offset, dx, opts);
-                    if (ret >= 0)  return ret;
-                    op = op.getChild();
-                }
-                break;
-
-            case Op.UNION:
-                for (int i = 0;  i < op.size();  i ++) {
-                    int ret = this. matchCharArray (con, op.elementAt(i), offset, dx, opts);
-                    //System.err.println("UNION: "+i+", ret="+ret);
-                    if (ret >= 0)  return ret;
-                }
-                return -1;
-
-            case Op.CAPTURE:
-                int refno = op.getData();
-                if (con.match != null && refno > 0) {
-                    int save = con.match.getBeginning(refno);
-                    con.match.setBeginning(refno, offset);
-                    int ret = this. matchCharArray (con, op.next, offset, dx, opts);
-                    if (ret < 0)  con.match.setBeginning(refno, save);
-                    return ret;
-                } else if (con.match != null && refno < 0) {
-                    int index = -refno;
-                    int save = con.match.getEnd(index);
-                    con.match.setEnd(index, offset);
-                    int ret = this. matchCharArray (con, op.next, offset, dx, opts);
-                    if (ret < 0)  con.match.setEnd(index, save);
-                    return ret;
-                }
-                op = op.next;
-                break;
-
-            case Op.LOOKAHEAD:
-                if (0 > this. matchCharArray (con, op.getChild(), offset, 1, opts))  return -1;
-                op = op.next;
-                break;
-            case Op.NEGATIVELOOKAHEAD:
-                if (0 <= this. matchCharArray (con, op.getChild(), offset, 1, opts))  return -1;
-                op = op.next;
-                break;
-            case Op.LOOKBEHIND:
-                if (0 > this. matchCharArray (con, op.getChild(), offset, -1, opts))  return -1;
-                op = op.next;
-                break;
-            case Op.NEGATIVELOOKBEHIND:
-                if (0 <= this. matchCharArray (con, op.getChild(), offset, -1, opts))  return -1;
-                op = op.next;
-                break;
-
-            case Op.INDEPENDENT:
-                {
-                    int ret = this. matchCharArray (con, op.getChild(), offset, dx, opts);
-                    if (ret < 0)  return ret;
-                    offset = ret;
-                    op = op.next;
-                }
-                break;
-
-            case Op.MODIFIER:
-                {
-                    int localopts = opts;
-                    localopts |= op.getData();
-                    localopts &= ~op.getData2();
-                    //System.err.println("MODIFIER: "+Integer.toString(opts, 16)+" -> "+Integer.toString(localopts, 16));
-                    int ret = this. matchCharArray (con, op.getChild(), offset, dx, localopts);
-                    if (ret < 0)  return ret;
-                    offset = ret;
-                    op = op.next;
-                }
-                break;
-
-            case Op.CONDITION:
-                {
-                    Op.ConditionOp cop = (Op.ConditionOp)op;
-                    boolean matchp = false;
-                    if (cop.refNumber > 0) {
-                        if (cop.refNumber >= this.nofparen)
-                            throw new RuntimeException("Internal Error: Reference number must be more than zero: "+cop.refNumber);
-                        matchp = con.match.getBeginning(cop.refNumber) >= 0
-                                 && con.match.getEnd(cop.refNumber) >= 0;
-                    } else {
-                        matchp = 0 <= this. matchCharArray (con, cop.condition, offset, dx, opts);
-                    }
-
-                    if (matchp) {
-                        op = cop.yes;
-                    } else if (cop.no != null) {
-                        op = cop.no;
-                    } else {
-                        op = cop.next;
-                    }
-                }
-                break;
-
-            default:
-                throw new RuntimeException("Unknown operation type: "+op.type);
-            } // switch (op.type)
-        } // while
-    }
-
-    private static final int getPreviousWordType(char[]  target, int begin, int end,
-                                                 int offset, int opts) {
-        int ret = getWordType(target, begin, end, --offset, opts);
-        while (ret == WT_IGNORE)
-            ret = getWordType(target, begin, end, --offset, opts);
-        return ret;
-    }
-
-    private static final int getWordType(char[]  target, int begin, int end,
-                                         int offset, int opts) {
-        if (offset < begin || offset >= end)  return WT_OTHER;
-        return getWordType0( target [  offset ] , opts);
-    }
-
-
-
-    private static final boolean regionMatches(char[]  target, int offset, int limit,
-                                               String part, int partlen) {
-        if (offset < 0)  return false;
-        if (limit-offset < partlen)
-            return false;
-        int i = 0;
-        while (partlen-- > 0) {
-            if ( target [  offset++ ]  != part.charAt(i++))
-                return false;
-        }
-        return true;
-    }
-
-    private static final boolean regionMatches(char[]  target, int offset, int limit,
-                                               int offset2, int partlen) {
-        if (offset < 0)  return false;
-        if (limit-offset < partlen)
-            return false;
-        int i = offset2;
-        while (partlen-- > 0) {
-            if ( target [  offset++ ]  !=  target [  i++ ] )
-                return false;
-        }
-        return true;
-    }
-
-/**
- * @see java.lang.String#regionMatches
- */
-    private static final boolean regionMatchesIgnoreCase(char[]  target, int offset, int limit,
-                                                         String part, int partlen) {
-        if (offset < 0)  return false;
-        if (limit-offset < partlen)
-            return false;
-        int i = 0;
-        while (partlen-- > 0) {
-            char ch1 =  target [  offset++ ] ;
-            char ch2 = part.charAt(i++);
-            if (ch1 == ch2)
-                continue;
-            char uch1 = Character.toUpperCase(ch1);
-            char uch2 = Character.toUpperCase(ch2);
-            if (uch1 == uch2)
-                continue;
-            if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2))
-                return false;
-        }
-        return true;
-    }
-
-    private static final boolean regionMatchesIgnoreCase(char[]  target, int offset, int limit,
-                                                         int offset2, int partlen) {
-        if (offset < 0)  return false;
-        if (limit-offset < partlen)
-            return false;
-        int i = offset2;
-        while (partlen-- > 0) {
-            char ch1 =  target [  offset++ ] ;
-            char ch2 =  target [  i++ ] ;
-            if (ch1 == ch2)
-                continue;
-            char uch1 = Character.toUpperCase(ch1);
-            char uch2 = Character.toUpperCase(ch2);
-            if (uch1 == uch2)
-                continue;
-            if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2))
-                return false;
-        }
-        return true;
-    }
-
-
-
-
-    /**
-     * Checks whether the <var>target</var> text <strong>contains</strong> this pattern or not.
-     *
-     * @return true if the target is matched to this regular expression.
-     */
-    public boolean matches(String  target) {
-        return this.matches(target, 0,  target .length() , (Match)null);
-    }
-
-    /**
-     * Checks whether the <var>target</var> text <strong>contains</strong> this pattern
-     * in specified range or not.
-     *
-     * @param start Start offset of the range.
-     * @param end  End offset +1 of the range.
-     * @return true if the target is matched to this regular expression.
-     */
-    public boolean matches(String  target, int start, int end) {
-        return this.matches(target, start, end, (Match)null);
-    }
-
-    /**
-     * Checks whether the <var>target</var> text <strong>contains</strong> this pattern or not.
-     *
-     * @param match A Match instance for storing matching result.
-     * @return Offset of the start position in <VAR>target</VAR>; or -1 if not match.
-     */
-    public boolean matches(String  target, Match match) {
-        return this.matches(target, 0,  target .length() , match);
-    }
-
-    /**
-     * Checks whether the <var>target</var> text <strong>contains</strong> this pattern
-     * in specified range or not.
-     *
-     * @param start Start offset of the range.
-     * @param end  End offset +1 of the range.
-     * @param match A Match instance for storing matching result.
-     * @return Offset of the start position in <VAR>target</VAR>; or -1 if not match.
-     */
-    public boolean matches(String  target, int start, int end, Match match) {
-
-        synchronized (this) {
-            if (this.operations == null)
-                this.prepare();
-            if (this.context == null)
-                this.context = new Context();
-        }
-        Context con = null;
-        synchronized (this.context) {
-            con = this.context.inuse ? new Context() : this.context;
-            con.reset(target, start, end, this.numberOfClosures);
-        }
-        if (match != null) {
-            match.setNumberOfGroups(this.nofparen);
-            match.setSource(target);
-        } else if (this.hasBackReferences) {
-            match = new Match();
-            match.setNumberOfGroups(this.nofparen);
-            // Need not to call setSource() because
-            // a caller can not access this match instance.
-        }
-        con.match = match;
-
-        if (this.isSet(this.options, XMLSCHEMA_MODE)) {
-            int matchEnd = this. matchString (con, this.operations, con.start, 1, this.options);
-            //System.err.println("DEBUG: matchEnd="+matchEnd);
-            if (matchEnd == con.limit) {
-                if (con.match != null) {
-                    con.match.setBeginning(0, con.start);
-                    con.match.setEnd(0, matchEnd);
-                }
-                con.inuse = false;
-                return true;
-            }
-            return false;
-        }
-
-        /*
-         * The pattern has only fixed string.
-         * The engine uses Boyer-Moore.
-         */
-        if (this.fixedStringOnly) {
-            //System.err.println("DEBUG: fixed-only: "+this.fixedString);
-            int o = this.fixedStringTable.matches(target, con.start, con.limit);
-            if (o >= 0) {
-                if (con.match != null) {
-                    con.match.setBeginning(0, o);
-                    con.match.setEnd(0, o+this.fixedString.length());
-                }
-                con.inuse = false;
-                return true;
-            }
-            con.inuse = false;
-            return false;
-        }
-
-        /*
-         * The pattern contains a fixed string.
-         * The engine checks with Boyer-Moore whether the text contains the fixed string or not.
-         * If not, it return with false.
-         */
-        if (this.fixedString != null) {
-            int o = this.fixedStringTable.matches(target, con.start, con.limit);
-            if (o < 0) {
-                //System.err.println("Non-match in fixed-string search.");
-                con.inuse = false;
-                return false;
-            }
-        }
-
-        int limit = con.limit-this.minlength;
-        int matchStart;
-        int matchEnd = -1;
-
-        /*
-         * Checks whether the expression starts with ".*".
-         */
-        if (this.operations != null
-            && this.operations.type == Op.CLOSURE && this.operations.getChild().type == Op.DOT) {
-            if (isSet(this.options, SINGLE_LINE)) {
-                matchStart = con.start;
-                matchEnd = this. matchString (con, this.operations, con.start, 1, this.options);
-            } else {
-                boolean previousIsEOL = true;
-                for (matchStart = con.start;  matchStart <= limit;  matchStart ++) {
-                    int ch =  target .charAt(  matchStart ) ;
-                    if (isEOLChar(ch)) {
-                        previousIsEOL = true;
-                    } else {
-                        if (previousIsEOL) {
-                            if (0 <= (matchEnd = this. matchString (con, this.operations,
-                                                                    matchStart, 1, this.options)))
-                                break;
-                        }
-                        previousIsEOL = false;
-                    }
-                }
-            }
-        }
-
-        /*
-         * Optimization against the first character.
-         */
-        else if (this.firstChar != null) {
-            //System.err.println("DEBUG: with firstchar-matching: "+this.firstChar);
-            RangeToken range = this.firstChar;
-            if (this.isSet(this.options, IGNORE_CASE)) {
-                range = this.firstChar.getCaseInsensitiveToken();
-                for (matchStart = con.start;  matchStart <= limit;  matchStart ++) {
-                    int ch =  target .charAt(  matchStart ) ;
-                    if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) {
-                        ch = REUtil.composeFromSurrogates(ch,  target .charAt(  matchStart+1 ) );
-                        if (!range.match(ch))  continue;
-                    } else {
-                        if (!range.match(ch)) {
-                            char ch1 = Character.toUpperCase((char)ch);
-                            if (!range.match(ch1))
-                                if (!range.match(Character.toLowerCase(ch1)))
-                                    continue;
-                        }
-                    }
-                    if (0 <= (matchEnd = this. matchString (con, this.operations,
-                                                            matchStart, 1, this.options)))
-                        break;
-                }
-            } else {
-                for (matchStart = con.start;  matchStart <= limit;  matchStart ++) {
-                    int ch =  target .charAt(  matchStart ) ;
-                    if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit)
-                        ch = REUtil.composeFromSurrogates(ch,  target .charAt(  matchStart+1 ) );
-                    if (!range.match(ch))  continue;
-                    if (0 <= (matchEnd = this. matchString (con, this.operations,
-                                                            matchStart, 1, this.options)))
-                        break;
-                }
-            }
-        }
-
-        /*
-         * Straightforward matching.
-         */
-        else {
-            for (matchStart = con.start;  matchStart <= limit;  matchStart ++) {
-                if (0 <= (matchEnd = this. matchString (con, this.operations, matchStart, 1, this.options)))
-                    break;
-            }
-        }
-
-        if (matchEnd >= 0) {
-            if (con.match != null) {
-                con.match.setBeginning(0, matchStart);
-                con.match.setEnd(0, matchEnd);
-            }
-            con.inuse = false;
-            return true;
-        } else {
-            con.inuse = false;
-            return false;
-        }
-    }
-
-    /**
-     * @return -1 when not match; offset of the end of matched string when match.
-     */
-    private int matchString (Context con, Op op, int offset, int dx, int opts) {
-
-
-
-
-        String target = con.strTarget;
-
-
-
-
-        while (true) {
-            if (op == null)
-                return offset;
-            if (offset > con.limit || offset < con.start)
-                return -1;
-            switch (op.type) {
-            case Op.CHAR:
-                if (isSet(opts, IGNORE_CASE)) {
-                    int ch = op.getData();
-                    if (dx > 0) {
-                        if (offset >= con.limit || !matchIgnoreCase(ch,  target .charAt(  offset ) ))
-                            return -1;
-                        offset ++;
-                    } else {
-                        int o1 = offset-1;
-                        if (o1 >= con.limit || o1 < 0 || !matchIgnoreCase(ch,  target .charAt(  o1 ) ))
-                            return -1;
-                        offset = o1;
-                    }
-                } else {
-                    int ch = op.getData();
-                    if (dx > 0) {
-                        if (offset >= con.limit || ch !=  target .charAt(  offset ) )
-                            return -1;
-                        offset ++;
-                    } else {
-                        int o1 = offset-1;
-                        if (o1 >= con.limit || o1 < 0 || ch !=  target .charAt(  o1 ) )
-                            return -1;
-                        offset = o1;
-                    }
-                }
-                op = op.next;
-                break;
-
-            case Op.DOT:
-                if (dx > 0) {
-                    if (offset >= con.limit)
-                        return -1;
-                    int ch =  target .charAt(  offset ) ;
-                    if (isSet(opts, SINGLE_LINE)) {
-                        if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit)
-                            offset ++;
-                    } else {
-                        if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit)
-                            ch = REUtil.composeFromSurrogates(ch,  target .charAt(  ++offset ) );
-                        if (isEOLChar(ch))
-                            return -1;
-                    }
-                    offset ++;
-                } else {
-                    int o1 = offset-1;
-                    if (o1 >= con.limit || o1 < 0)
-                        return -1;
-                    int ch =  target .charAt(  o1 ) ;
-                    if (isSet(opts, SINGLE_LINE)) {
-                        if (REUtil.isLowSurrogate(ch) && o1-1 >= 0)
-                            o1 --;
-                    } else {
-                        if (REUtil.isLowSurrogate(ch) && o1-1 >= 0)
-                            ch = REUtil.composeFromSurrogates( target .charAt(  --o1 ) , ch);
-                        if (!isEOLChar(ch))
-                            return -1;
-                    }
-                    offset = o1;
-                }
-                op = op.next;
-                break;
-
-            case Op.RANGE:
-            case Op.NRANGE:
-                if (dx > 0) {
-                    if (offset >= con.limit)
-                        return -1;
-                    int ch =  target .charAt(  offset ) ;
-                    if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit)
-                        ch = REUtil.composeFromSurrogates(ch,  target .charAt(  ++offset ) );
-                    RangeToken tok = op.getToken();
-                    if (isSet(opts, IGNORE_CASE)) {
-                        tok = tok.getCaseInsensitiveToken();
-                        if (!tok.match(ch)) {
-                            if (ch >= 0x10000)  return -1;
-                            char uch;
-                            if (!tok.match(uch = Character.toUpperCase((char)ch))
-                                && !tok.match(Character.toLowerCase(uch)))
-                                return -1;
-                        }
-                    } else {
-                        if (!tok.match(ch))  return -1;
-                    }
-                    offset ++;
-                } else {
-                    int o1 = offset-1;
-                    if (o1 >= con.limit || o1 < 0)
-                        return -1;
-                    int ch =  target .charAt(  o1 ) ;
-                    if (REUtil.isLowSurrogate(ch) && o1-1 >= 0)
-                        ch = REUtil.composeFromSurrogates( target .charAt(  --o1 ) , ch);
-                    RangeToken tok = op.getToken();
-                    if (isSet(opts, IGNORE_CASE)) {
-                        tok = tok.getCaseInsensitiveToken();
-                        if (!tok.match(ch)) {
-                            if (ch >= 0x10000)  return -1;
-                            char uch;
-                            if (!tok.match(uch = Character.toUpperCase((char)ch))
-                                && !tok.match(Character.toLowerCase(uch)))
-                                return -1;
-                        }
-                    } else {
-                        if (!tok.match(ch))  return -1;
-                    }
-                    offset = o1;
-                }
-                op = op.next;
-                break;
-
-            case Op.ANCHOR:
-                boolean go = false;
-                switch (op.getData()) {
-                case '^':
-                    if (isSet(opts, MULTIPLE_LINES)) {
-                        if (!(offset == con.start
-                              || offset > con.start && isEOLChar( target .charAt(  offset-1 ) )))
-                            return -1;
-                    } else {
-                        if (offset != con.start)
-                            return -1;
-                    }
-                    break;
-
-                case '@':                         // Internal use only.
-                    // The @ always matches line beginnings.
-                    if (!(offset == con.start
-                          || offset > con.start && isEOLChar( target .charAt(  offset-1 ) )))
-                        return -1;
-                    break;
-
-                case '$':
-                    if (isSet(opts, MULTIPLE_LINES)) {
-                        if (!(offset == con.limit
-                              || offset < con.limit && isEOLChar( target .charAt(  offset ) )))
-                            return -1;
-                    } else {
-                        if (!(offset == con.limit
-                              || offset+1 == con.limit && isEOLChar( target .charAt(  offset ) )
-                              || offset+2 == con.limit &&  target .charAt(  offset )  == CARRIAGE_RETURN
-                              &&  target .charAt(  offset+1 )  == LINE_FEED))
-                            return -1;
-                    }
-                    break;
-
-                case 'A':
-                    if (offset != con.start)  return -1;
-                    break;
-
-                case 'Z':
-                    if (!(offset == con.limit
-                          || offset+1 == con.limit && isEOLChar( target .charAt(  offset ) )
-                          || offset+2 == con.limit &&  target .charAt(  offset )  == CARRIAGE_RETURN
-                          &&  target .charAt(  offset+1 )  == LINE_FEED))
-                        return -1;
-                    break;
-
-                case 'z':
-                    if (offset != con.limit)  return -1;
-                    break;
-
-                case 'b':
-                    if (con.length == 0)  return -1;
-                    {
-                        int after = getWordType(target, con.start, con.limit, offset, opts);
-                        if (after == WT_IGNORE)  return -1;
-                        int before = getPreviousWordType(target, con.start, con.limit, offset, opts);
-                        if (after == before)  return -1;
-                    }
-                    break;
-
-                case 'B':
-                    if (con.length == 0)
-                        go = true;
-                    else {
-                        int after = getWordType(target, con.start, con.limit, offset, opts);
-                        go = after == WT_IGNORE
-                             || after == getPreviousWordType(target, con.start, con.limit, offset, opts);
-                    }
-                    if (!go)  return -1;
-                    break;
-
-                case '<':
-                    if (con.length == 0 || offset == con.limit)  return -1;
-                    if (getWordType(target, con.start, con.limit, offset, opts) != WT_LETTER
-                        || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_OTHER)
-                        return -1;
-                    break;
-
-                case '>':
-                    if (con.length == 0 || offset == con.start)  return -1;
-                    if (getWordType(target, con.start, con.limit, offset, opts) != WT_OTHER
-                        || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_LETTER)
-                        return -1;
-                    break;
-                } // switch anchor type
-                op = op.next;
-                break;
-
-            case Op.BACKREFERENCE:
-                {
-                    int refno = op.getData();
-                    if (refno <= 0 || refno >= this.nofparen)
-                        throw new RuntimeException("Internal Error: Reference number must be more than zero: "+refno);
-                    if (con.match.getBeginning(refno) < 0
-                        || con.match.getEnd(refno) < 0)
-                        return -1;                // ********
-                    int o2 = con.match.getBeginning(refno);
-                    int literallen = con.match.getEnd(refno)-o2;
-                    if (!isSet(opts, IGNORE_CASE)) {
-                        if (dx > 0) {
-                            if (!regionMatches(target, offset, con.limit, o2, literallen))
-                                return -1;
-                            offset += literallen;
-                        } else {
-                            if (!regionMatches(target, offset-literallen, con.limit, o2, literallen))
-                                return -1;
-                            offset -= literallen;
-                        }
-                    } else {
-                        if (dx > 0) {
-                            if (!regionMatchesIgnoreCase(target, offset, con.limit, o2, literallen))
-                                return -1;
-                            offset += literallen;
-                        } else {
-                            if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit,
-                                                         o2, literallen))
-                                return -1;
-                            offset -= literallen;
-                        }
-                    }
-                }
-                op = op.next;
-                break;
-            case Op.STRING:
-                {
-                    String literal = op.getString();
-                    int literallen = literal.length();
-                    if (!isSet(opts, IGNORE_CASE)) {
-                        if (dx > 0) {
-                            if (!regionMatches(target, offset, con.limit, literal, literallen))
-                                return -1;
-                            offset += literallen;
-                        } else {
-                            if (!regionMatches(target, offset-literallen, con.limit, literal, literallen))
-                                return -1;
-                            offset -= literallen;
-                        }
-                    } else {
-                        if (dx > 0) {
-                            if (!regionMatchesIgnoreCase(target, offset, con.limit, literal, literallen))
-                                return -1;
-                            offset += literallen;
-                        } else {
-                            if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit,
-                                                         literal, literallen))
-                                return -1;
-                            offset -= literallen;
-                        }
-                    }
-                }
-                op = op.next;
-                break;
-
-            case Op.CLOSURE:
-                {
-                    /*
-                     * Saves current position to avoid
-                     * zero-width repeats.
-                     */
-                    int id = op.getData();
-                    if (id >= 0) {
-                        int previousOffset = con.offsets[id];
-                        if (previousOffset < 0 || previousOffset != offset) {
-                            con.offsets[id] = offset;
-                        } else {
-                            con.offsets[id] = -1;
-                            op = op.next;
-                            break;
-                        }
-                    }
-
-                    int ret = this. matchString (con, op.getChild(), offset, dx, opts);
-                    if (id >= 0)  con.offsets[id] = -1;
-                    if (ret >= 0)  return ret;
-                    op = op.next;
-                }
-                break;
-
-            case Op.QUESTION:
-                {
-                    int ret = this. matchString (con, op.getChild(), offset, dx, opts);
-                    if (ret >= 0)  return ret;
-                    op = op.next;
-                }
-                break;
-
-            case Op.NONGREEDYCLOSURE:
-            case Op.NONGREEDYQUESTION:
-                {
-                    int ret = this. matchString (con, op.next, offset, dx, opts);
-                    if (ret >= 0)  return ret;
-                    op = op.getChild();
-                }
-                break;
-
-            case Op.UNION:
-                for (int i = 0;  i < op.size();  i ++) {
-                    int ret = this. matchString (con, op.elementAt(i), offset, dx, opts);
-                    //System.err.println("UNION: "+i+", ret="+ret);
-                    if (ret >= 0)  return ret;
-                }
-                return -1;
-
-            case Op.CAPTURE:
-                int refno = op.getData();
-                if (con.match != null && refno > 0) {
-                    int save = con.match.getBeginning(refno);
-                    con.match.setBeginning(refno, offset);
-                    int ret = this. matchString (con, op.next, offset, dx, opts);
-                    if (ret < 0)  con.match.setBeginning(refno, save);
-                    return ret;
-                } else if (con.match != null && refno < 0) {
-                    int index = -refno;
-                    int save = con.match.getEnd(index);
-                    con.match.setEnd(index, offset);
-                    int ret = this. matchString (con, op.next, offset, dx, opts);
-                    if (ret < 0)  con.match.setEnd(index, save);
-                    return ret;
-                }
-                op = op.next;
-                break;
-
-            case Op.LOOKAHEAD:
-                if (0 > this. matchString (con, op.getChild(), offset, 1, opts))  return -1;
-                op = op.next;
-                break;
-            case Op.NEGATIVELOOKAHEAD:
-                if (0 <= this. matchString (con, op.getChild(), offset, 1, opts))  return -1;
-                op = op.next;
-                break;
-            case Op.LOOKBEHIND:
-                if (0 > this. matchString (con, op.getChild(), offset, -1, opts))  return -1;
-                op = op.next;
-                break;
-            case Op.NEGATIVELOOKBEHIND:
-                if (0 <= this. matchString (con, op.getChild(), offset, -1, opts))  return -1;
-                op = op.next;
-                break;
-
-            case Op.INDEPENDENT:
-                {
-                    int ret = this. matchString (con, op.getChild(), offset, dx, opts);
-                    if (ret < 0)  return ret;
-                    offset = ret;
-                    op = op.next;
-                }
-                break;
-
-            case Op.MODIFIER:
-                {
-                    int localopts = opts;
-                    localopts |= op.getData();
-                    localopts &= ~op.getData2();
-                    //System.err.println("MODIFIER: "+Integer.toString(opts, 16)+" -> "+Integer.toString(localopts, 16));
-                    int ret = this. matchString (con, op.getChild(), offset, dx, localopts);
-                    if (ret < 0)  return ret;
-                    offset = ret;
-                    op = op.next;
-                }
-                break;
-
-            case Op.CONDITION:
-                {
-                    Op.ConditionOp cop = (Op.ConditionOp)op;
-                    boolean matchp = false;
-                    if (cop.refNumber > 0) {
-                        if (cop.refNumber >= this.nofparen)
-                            throw new RuntimeException("Internal Error: Reference number must be more than zero: "+cop.refNumber);
-                        matchp = con.match.getBeginning(cop.refNumber) >= 0
-                                 && con.match.getEnd(cop.refNumber) >= 0;
-                    } else {
-                        matchp = 0 <= this. matchString (con, cop.condition, offset, dx, opts);
-                    }
-
-                    if (matchp) {
-                        op = cop.yes;
-                    } else if (cop.no != null) {
-                        op = cop.no;
-                    } else {
-                        op = cop.next;
-                    }
-                }
-                break;
-
-            default:
-                throw new RuntimeException("Unknown operation type: "+op.type);
-            } // switch (op.type)
-        } // while
-    }
-
-    private static final int getPreviousWordType(String  target, int begin, int end,
-                                                 int offset, int opts) {
-        int ret = getWordType(target, begin, end, --offset, opts);
-        while (ret == WT_IGNORE)
-            ret = getWordType(target, begin, end, --offset, opts);
-        return ret;
-    }
-
-    private static final int getWordType(String  target, int begin, int end,
-                                         int offset, int opts) {
-        if (offset < begin || offset >= end)  return WT_OTHER;
-        return getWordType0( target .charAt(  offset ) , opts);
-    }
-
-
-    private static final boolean regionMatches(String text, int offset, int limit,
-                                               String part, int partlen) {
-        if (limit-offset < partlen)  return false;
-        return text.regionMatches(offset, part, 0, partlen);
-    }
-
-    private static final boolean regionMatches(String text, int offset, int limit,
-                                               int offset2, int partlen) {
-        if (limit-offset < partlen)  return false;
-        return text.regionMatches(offset, text, offset2, partlen);
-    }
-
-    private static final boolean regionMatchesIgnoreCase(String text, int offset, int limit,
-                                                         String part, int partlen) {
-        return text.regionMatches(true, offset, part, 0, partlen);
-    }
-
-    private static final boolean regionMatchesIgnoreCase(String text, int offset, int limit,
-                                                         int offset2, int partlen) {
-        if (limit-offset < partlen)  return false;
-        return text.regionMatches(true, offset, text, offset2, partlen);
-    }
-
-
-
-
-
-
-
-    /**
-     * Checks whether the <var>target</var> text <strong>contains</strong> this pattern or not.
-     *
-     * @return true if the target is matched to this regular expression.
-     */
-    public boolean matches(CharacterIterator target) {
-        return this.matches(target, (Match)null);
-    }
-
-
-    /**
-     * Checks whether the <var>target</var> text <strong>contains</strong> this pattern or not.
-     *
-     * @param match A Match instance for storing matching result.
-     * @return Offset of the start position in <VAR>target</VAR>; or -1 if not match.
-     */
-    public boolean matches(CharacterIterator  target, Match match) {
-        int start = target.getBeginIndex();
-        int end = target.getEndIndex();
-
-
-
-        synchronized (this) {
-            if (this.operations == null)
-                this.prepare();
-            if (this.context == null)
-                this.context = new Context();
-        }
-        Context con = null;
-        synchronized (this.context) {
-            con = this.context.inuse ? new Context() : this.context;
-            con.reset(target, start, end, this.numberOfClosures);
-        }
-        if (match != null) {
-            match.setNumberOfGroups(this.nofparen);
-            match.setSource(target);
-        } else if (this.hasBackReferences) {
-            match = new Match();
-            match.setNumberOfGroups(this.nofparen);
-            // Need not to call setSource() because
-            // a caller can not access this match instance.
-        }
-        con.match = match;
-
-        if (this.isSet(this.options, XMLSCHEMA_MODE)) {
-            int matchEnd = this. matchCharacterIterator (con, this.operations, con.start, 1, this.options);
-            //System.err.println("DEBUG: matchEnd="+matchEnd);
-            if (matchEnd == con.limit) {
-                if (con.match != null) {
-                    con.match.setBeginning(0, con.start);
-                    con.match.setEnd(0, matchEnd);
-                }
-                con.inuse = false;
-                return true;
-            }
-            return false;
-        }
-
-        /*
-         * The pattern has only fixed string.
-         * The engine uses Boyer-Moore.
-         */
-        if (this.fixedStringOnly) {
-            //System.err.println("DEBUG: fixed-only: "+this.fixedString);
-            int o = this.fixedStringTable.matches(target, con.start, con.limit);
-            if (o >= 0) {
-                if (con.match != null) {
-                    con.match.setBeginning(0, o);
-                    con.match.setEnd(0, o+this.fixedString.length());
-                }
-                con.inuse = false;
-                return true;
-            }
-            con.inuse = false;
-            return false;
-        }
-
-        /*
-         * The pattern contains a fixed string.
-         * The engine checks with Boyer-Moore whether the text contains the fixed string or not.
-         * If not, it return with false.
-         */
-        if (this.fixedString != null) {
-            int o = this.fixedStringTable.matches(target, con.start, con.limit);
-            if (o < 0) {
-                //System.err.println("Non-match in fixed-string search.");
-                con.inuse = false;
-                return false;
-            }
-        }
-
-        int limit = con.limit-this.minlength;
-        int matchStart;
-        int matchEnd = -1;
-
-        /*
-         * Checks whether the expression starts with ".*".
-         */
-        if (this.operations != null
-            && this.operations.type == Op.CLOSURE && this.operations.getChild().type == Op.DOT) {
-            if (isSet(this.options, SINGLE_LINE)) {
-                matchStart = con.start;
-                matchEnd = this. matchCharacterIterator (con, this.operations, con.start, 1, this.options);
-            } else {
-                boolean previousIsEOL = true;
-                for (matchStart = con.start;  matchStart <= limit;  matchStart ++) {
-                    int ch =  target .setIndex(  matchStart ) ;
-                    if (isEOLChar(ch)) {
-                        previousIsEOL = true;
-                    } else {
-                        if (previousIsEOL) {
-                            if (0 <= (matchEnd = this. matchCharacterIterator (con, this.operations,
-                                                                               matchStart, 1, this.options)))
-                                break;
-                        }
-                        previousIsEOL = false;
-                    }
-                }
-            }
-        }
-
-        /*
-         * Optimization against the first character.
-         */
-        else if (this.firstChar != null) {
-            //System.err.println("DEBUG: with firstchar-matching: "+this.firstChar);
-            RangeToken range = this.firstChar;
-            if (this.isSet(this.options, IGNORE_CASE)) {
-                range = this.firstChar.getCaseInsensitiveToken();
-                for (matchStart = con.start;  matchStart <= limit;  matchStart ++) {
-                    int ch =  target .setIndex(  matchStart ) ;
-                    if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) {
-                        ch = REUtil.composeFromSurrogates(ch,  target .setIndex(  matchStart+1 ) );
-                        if (!range.match(ch))  continue;
-                    } else {
-                        if (!range.match(ch)) {
-                            char ch1 = Character.toUpperCase((char)ch);
-                            if (!range.match(ch1))
-                                if (!range.match(Character.toLowerCase(ch1)))
-                                    continue;
-                        }
-                    }
-                    if (0 <= (matchEnd = this. matchCharacterIterator (con, this.operations,
-                                                                       matchStart, 1, this.options)))
-                        break;
-                }
-            } else {
-                for (matchStart = con.start;  matchStart <= limit;  matchStart ++) {
-                    int ch =  target .setIndex(  matchStart ) ;
-                    if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit)
-                        ch = REUtil.composeFromSurrogates(ch,  target .setIndex(  matchStart+1 ) );
-                    if (!range.match(ch))  continue;
-                    if (0 <= (matchEnd = this. matchCharacterIterator (con, this.operations,
-                                                                       matchStart, 1, this.options)))
-                        break;
-                }
-            }
-        }
-
-        /*
-         * Straightforward matching.
-         */
-        else {
-            for (matchStart = con.start;  matchStart <= limit;  matchStart ++) {
-                if (0 <= (matchEnd = this. matchCharacterIterator (con, this.operations, matchStart, 1, this.options)))
-                    break;
-            }
-        }
-
-        if (matchEnd >= 0) {
-            if (con.match != null) {
-                con.match.setBeginning(0, matchStart);
-                con.match.setEnd(0, matchEnd);
-            }
-            con.inuse = false;
-            return true;
-        } else {
-            con.inuse = false;
-            return false;
-        }
-    }
-
-    /**
-     * @return -1 when not match; offset of the end of matched string when match.
-     */
-    private int matchCharacterIterator (Context con, Op op, int offset, int dx, int opts) {
-
-
-        CharacterIterator target = con.ciTarget;
-
-
-
-
-
-
-        while (true) {
-            if (op == null)
-                return offset;
-            if (offset > con.limit || offset < con.start)
-                return -1;
-            switch (op.type) {
-            case Op.CHAR:
-                if (isSet(opts, IGNORE_CASE)) {
-                    int ch = op.getData();
-                    if (dx > 0) {
-                        if (offset >= con.limit || !matchIgnoreCase(ch,  target .setIndex(  offset ) ))
-                            return -1;
-                        offset ++;
-                    } else {
-                        int o1 = offset-1;
-                        if (o1 >= con.limit || o1 < 0 || !matchIgnoreCase(ch,  target .setIndex(  o1 ) ))
-                            return -1;
-                        offset = o1;
-                    }
-                } else {
-                    int ch = op.getData();
-                    if (dx > 0) {
-                        if (offset >= con.limit || ch !=  target .setIndex(  offset ) )
-                            return -1;
-                        offset ++;
-                    } else {
-                        int o1 = offset-1;
-                        if (o1 >= con.limit || o1 < 0 || ch !=  target .setIndex(  o1 ) )
-                            return -1;
-                        offset = o1;
-                    }
-                }
-                op = op.next;
-                break;
-
-            case Op.DOT:
-                if (dx > 0) {
-                    if (offset >= con.limit)
-                        return -1;
-                    int ch =  target .setIndex(  offset ) ;
-                    if (isSet(opts, SINGLE_LINE)) {
-                        if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit)
-                            offset ++;
-                    } else {
-                        if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit)
-                            ch = REUtil.composeFromSurrogates(ch,  target .setIndex(  ++offset ) );
-                        if (isEOLChar(ch))
-                            return -1;
-                    }
-                    offset ++;
-                } else {
-                    int o1 = offset-1;
-                    if (o1 >= con.limit || o1 < 0)
-                        return -1;
-                    int ch =  target .setIndex(  o1 ) ;
-                    if (isSet(opts, SINGLE_LINE)) {
-                        if (REUtil.isLowSurrogate(ch) && o1-1 >= 0)
-                            o1 --;
-                    } else {
-                        if (REUtil.isLowSurrogate(ch) && o1-1 >= 0)
-                            ch = REUtil.composeFromSurrogates( target .setIndex(  --o1 ) , ch);
-                        if (!isEOLChar(ch))
-                            return -1;
-                    }
-                    offset = o1;
-                }
-                op = op.next;
-                break;
-
-            case Op.RANGE:
-            case Op.NRANGE:
-                if (dx > 0) {
-                    if (offset >= con.limit)
-                        return -1;
-                    int ch =  target .setIndex(  offset ) ;
-                    if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit)
-                        ch = REUtil.composeFromSurrogates(ch,  target .setIndex(  ++offset ) );
-                    RangeToken tok = op.getToken();
-                    if (isSet(opts, IGNORE_CASE)) {
-                        tok = tok.getCaseInsensitiveToken();
-                        if (!tok.match(ch)) {
-                            if (ch >= 0x10000)  return -1;
-                            char uch;
-                            if (!tok.match(uch = Character.toUpperCase((char)ch))
-                                && !tok.match(Character.toLowerCase(uch)))
-                                return -1;
-                        }
-                    } else {
-                        if (!tok.match(ch))  return -1;
-                    }
-                    offset ++;
-                } else {
-                    int o1 = offset-1;
-                    if (o1 >= con.limit || o1 < 0)
-                        return -1;
-                    int ch =  target .setIndex(  o1 ) ;
-                    if (REUtil.isLowSurrogate(ch) && o1-1 >= 0)
-                        ch = REUtil.composeFromSurrogates( target .setIndex(  --o1 ) , ch);
-                    RangeToken tok = op.getToken();
-                    if (isSet(opts, IGNORE_CASE)) {
-                        tok = tok.getCaseInsensitiveToken();
-                        if (!tok.match(ch)) {
-                            if (ch >= 0x10000)  return -1;
-                            char uch;
-                            if (!tok.match(uch = Character.toUpperCase((char)ch))
-                                && !tok.match(Character.toLowerCase(uch)))
-                                return -1;
-                        }
-                    } else {
-                        if (!tok.match(ch))  return -1;
-                    }
-                    offset = o1;
-                }
-                op = op.next;
-                break;
-
-            case Op.ANCHOR:
-                boolean go = false;
-                switch (op.getData()) {
-                case '^':
-                    if (isSet(opts, MULTIPLE_LINES)) {
-                        if (!(offset == con.start
-                              || offset > con.start && isEOLChar( target .setIndex(  offset-1 ) )))
-                            return -1;
-                    } else {
-                        if (offset != con.start)
-                            return -1;
-                    }
-                    break;
-
-                case '@':                         // Internal use only.
-                    // The @ always matches line beginnings.
-                    if (!(offset == con.start
-                          || offset > con.start && isEOLChar( target .setIndex(  offset-1 ) )))
-                        return -1;
-                    break;
-
-                case '$':
-                    if (isSet(opts, MULTIPLE_LINES)) {
-                        if (!(offset == con.limit
-                              || offset < con.limit && isEOLChar( target .setIndex(  offset ) )))
-                            return -1;
-                    } else {
-                        if (!(offset == con.limit
-                              || offset+1 == con.limit && isEOLChar( target .setIndex(  offset ) )
-                              || offset+2 == con.limit &&  target .setIndex(  offset )  == CARRIAGE_RETURN
-                              &&  target .setIndex(  offset+1 )  == LINE_FEED))
-                            return -1;
-                    }
-                    break;
-
-                case 'A':
-                    if (offset != con.start)  return -1;
-                    break;
-
-                case 'Z':
-                    if (!(offset == con.limit
-                          || offset+1 == con.limit && isEOLChar( target .setIndex(  offset ) )
-                          || offset+2 == con.limit &&  target .setIndex(  offset )  == CARRIAGE_RETURN
-                          &&  target .setIndex(  offset+1 )  == LINE_FEED))
-                        return -1;
-                    break;
-
-                case 'z':
-                    if (offset != con.limit)  return -1;
-                    break;
-
-                case 'b':
-                    if (con.length == 0)  return -1;
-                    {
-                        int after = getWordType(target, con.start, con.limit, offset, opts);
-                        if (after == WT_IGNORE)  return -1;
-                        int before = getPreviousWordType(target, con.start, con.limit, offset, opts);
-                        if (after == before)  return -1;
-                    }
-                    break;
-
-                case 'B':
-                    if (con.length == 0)
-                        go = true;
-                    else {
-                        int after = getWordType(target, con.start, con.limit, offset, opts);
-                        go = after == WT_IGNORE
-                             || after == getPreviousWordType(target, con.start, con.limit, offset, opts);
-                    }
-                    if (!go)  return -1;
-                    break;
-
-                case '<':
-                    if (con.length == 0 || offset == con.limit)  return -1;
-                    if (getWordType(target, con.start, con.limit, offset, opts) != WT_LETTER
-                        || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_OTHER)
-                        return -1;
-                    break;
-
-                case '>':
-                    if (con.length == 0 || offset == con.start)  return -1;
-                    if (getWordType(target, con.start, con.limit, offset, opts) != WT_OTHER
-                        || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_LETTER)
-                        return -1;
-                    break;
-                } // switch anchor type
-                op = op.next;
-                break;
-
-            case Op.BACKREFERENCE:
-                {
-                    int refno = op.getData();
-                    if (refno <= 0 || refno >= this.nofparen)
-                        throw new RuntimeException("Internal Error: Reference number must be more than zero: "+refno);
-                    if (con.match.getBeginning(refno) < 0
-                        || con.match.getEnd(refno) < 0)
-                        return -1;                // ********
-                    int o2 = con.match.getBeginning(refno);
-                    int literallen = con.match.getEnd(refno)-o2;
-                    if (!isSet(opts, IGNORE_CASE)) {
-                        if (dx > 0) {
-                            if (!regionMatches(target, offset, con.limit, o2, literallen))
-                                return -1;
-                            offset += literallen;
-                        } else {
-                            if (!regionMatches(target, offset-literallen, con.limit, o2, literallen))
-                                return -1;
-                            offset -= literallen;
-                        }
-                    } else {
-                        if (dx > 0) {
-                            if (!regionMatchesIgnoreCase(target, offset, con.limit, o2, literallen))
-                                return -1;
-                            offset += literallen;
-                        } else {
-                            if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit,
-                                                         o2, literallen))
-                                return -1;
-                            offset -= literallen;
-                        }
-                    }
-                }
-                op = op.next;
-                break;
-            case Op.STRING:
-                {
-                    String literal = op.getString();
-                    int literallen = literal.length();
-                    if (!isSet(opts, IGNORE_CASE)) {
-                        if (dx > 0) {
-                            if (!regionMatches(target, offset, con.limit, literal, literallen))
-                                return -1;
-                            offset += literallen;
-                        } else {
-                            if (!regionMatches(target, offset-literallen, con.limit, literal, literallen))
-                                return -1;
-                            offset -= literallen;
-                        }
-                    } else {
-                        if (dx > 0) {
-                            if (!regionMatchesIgnoreCase(target, offset, con.limit, literal, literallen))
-                                return -1;
-                            offset += literallen;
-                        } else {
-                            if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit,
-                                                         literal, literallen))
-                                return -1;
-                            offset -= literallen;
-                        }
-                    }
-                }
-                op = op.next;
-                break;
-
-            case Op.CLOSURE:
-                {
-                    /*
-                     * Saves current position to avoid
-                     * zero-width repeats.
-                     */
-                    int id = op.getData();
-                    if (id >= 0) {
-                        int previousOffset = con.offsets[id];
-                        if (previousOffset < 0 || previousOffset != offset) {
-                            con.offsets[id] = offset;
-                        } else {
-                            con.offsets[id] = -1;
-                            op = op.next;
-                            break;
-                        }
-                    }
-
-                    int ret = this. matchCharacterIterator (con, op.getChild(), offset, dx, opts);
-                    if (id >= 0)  con.offsets[id] = -1;
-                    if (ret >= 0)  return ret;
-                    op = op.next;
-                }
-                break;
-
-            case Op.QUESTION:
-                {
-                    int ret = this. matchCharacterIterator (con, op.getChild(), offset, dx, opts);
-                    if (ret >= 0)  return ret;
-                    op = op.next;
-                }
-                break;
-
-            case Op.NONGREEDYCLOSURE:
-            case Op.NONGREEDYQUESTION:
-                {
-                    int ret = this. matchCharacterIterator (con, op.next, offset, dx, opts);
-                    if (ret >= 0)  return ret;
-                    op = op.getChild();
-                }
-                break;
-
-            case Op.UNION:
-                for (int i = 0;  i < op.size();  i ++) {
-                    int ret = this. matchCharacterIterator (con, op.elementAt(i), offset, dx, opts);
-                    //System.err.println("UNION: "+i+", ret="+ret);
-                    if (ret >= 0)  return ret;
-                }
-                return -1;
-
-            case Op.CAPTURE:
-                int refno = op.getData();
-                if (con.match != null && refno > 0) {
-                    int save = con.match.getBeginning(refno);
-                    con.match.setBeginning(refno, offset);
-                    int ret = this. matchCharacterIterator (con, op.next, offset, dx, opts);
-                    if (ret < 0)  con.match.setBeginning(refno, save);
-                    return ret;
-                } else if (con.match != null && refno < 0) {
-                    int index = -refno;
-                    int save = con.match.getEnd(index);
-                    con.match.setEnd(index, offset);
-                    int ret = this. matchCharacterIterator (con, op.next, offset, dx, opts);
-                    if (ret < 0)  con.match.setEnd(index, save);
-                    return ret;
-                }
-                op = op.next;
-                break;
-
-            case Op.LOOKAHEAD:
-                if (0 > this. matchCharacterIterator (con, op.getChild(), offset, 1, opts))  return -1;
-                op = op.next;
-                break;
-            case Op.NEGATIVELOOKAHEAD:
-                if (0 <= this. matchCharacterIterator (con, op.getChild(), offset, 1, opts))  return -1;
-                op = op.next;
-                break;
-            case Op.LOOKBEHIND:
-                if (0 > this. matchCharacterIterator (con, op.getChild(), offset, -1, opts))  return -1;
-                op = op.next;
-                break;
-            case Op.NEGATIVELOOKBEHIND:
-                if (0 <= this. matchCharacterIterator (con, op.getChild(), offset, -1, opts))  return -1;
-                op = op.next;
-                break;
-
-            case Op.INDEPENDENT:
-                {
-                    int ret = this. matchCharacterIterator (con, op.getChild(), offset, dx, opts);
-                    if (ret < 0)  return ret;
-                    offset = ret;
-                    op = op.next;
-                }
-                break;
-
-            case Op.MODIFIER:
-                {
-                    int localopts = opts;
-                    localopts |= op.getData();
-                    localopts &= ~op.getData2();
-                    //System.err.println("MODIFIER: "+Integer.toString(opts, 16)+" -> "+Integer.toString(localopts, 16));
-                    int ret = this. matchCharacterIterator (con, op.getChild(), offset, dx, localopts);
-                    if (ret < 0)  return ret;
-                    offset = ret;
-                    op = op.next;
-                }
-                break;
-
-            case Op.CONDITION:
-                {
-                    Op.ConditionOp cop = (Op.ConditionOp)op;
-                    boolean matchp = false;
-                    if (cop.refNumber > 0) {
-                        if (cop.refNumber >= this.nofparen)
-                            throw new RuntimeException("Internal Error: Reference number must be more than zero: "+cop.refNumber);
-                        matchp = con.match.getBeginning(cop.refNumber) >= 0
-                                 && con.match.getEnd(cop.refNumber) >= 0;
-                    } else {
-                        matchp = 0 <= this. matchCharacterIterator (con, cop.condition, offset, dx, opts);
-                    }
-
-                    if (matchp) {
-                        op = cop.yes;
-                    } else if (cop.no != null) {
-                        op = cop.no;
-                    } else {
-                        op = cop.next;
-                    }
-                }
-                break;
-
-            default:
-                throw new RuntimeException("Unknown operation type: "+op.type);
-            } // switch (op.type)
-        } // while
-    }
-
-    private static final int getPreviousWordType(CharacterIterator  target, int begin, int end,
-                                                 int offset, int opts) {
-        int ret = getWordType(target, begin, end, --offset, opts);
-        while (ret == WT_IGNORE)
-            ret = getWordType(target, begin, end, --offset, opts);
-        return ret;
-    }
-
-    private static final int getWordType(CharacterIterator  target, int begin, int end,
-                                         int offset, int opts) {
-        if (offset < begin || offset >= end)  return WT_OTHER;
-        return getWordType0( target .setIndex(  offset ) , opts);
-    }
-
-
-
-    private static final boolean regionMatches(CharacterIterator  target, int offset, int limit,
-                                               String part, int partlen) {
-        if (offset < 0)  return false;
-        if (limit-offset < partlen)
-            return false;
-        int i = 0;
-        while (partlen-- > 0) {
-            if ( target .setIndex(  offset++ )  != part.charAt(i++))
-                return false;
-        }
-        return true;
-    }
-
-    private static final boolean regionMatches(CharacterIterator  target, int offset, int limit,
-                                               int offset2, int partlen) {
-        if (offset < 0)  return false;
-        if (limit-offset < partlen)
-            return false;
-        int i = offset2;
-        while (partlen-- > 0) {
-            if ( target .setIndex(  offset++ )  !=  target .setIndex(  i++ ) )
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * @see java.lang.String#regionMatches
-     */
-    private static final boolean regionMatchesIgnoreCase(CharacterIterator  target, int offset, int limit,
-                                                         String part, int partlen) {
-        if (offset < 0)  return false;
-        if (limit-offset < partlen)
-            return false;
-        int i = 0;
-        while (partlen-- > 0) {
-            char ch1 =  target .setIndex(  offset++ ) ;
-            char ch2 = part.charAt(i++);
-            if (ch1 == ch2)
-                continue;
-            char uch1 = Character.toUpperCase(ch1);
-            char uch2 = Character.toUpperCase(ch2);
-            if (uch1 == uch2)
-                continue;
-            if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2))
-                return false;
-        }
-        return true;
-    }
-
-    private static final boolean regionMatchesIgnoreCase(CharacterIterator  target, int offset, int limit,
-                                                         int offset2, int partlen) {
-        if (offset < 0)  return false;
-        if (limit-offset < partlen)
-            return false;
-        int i = offset2;
-        while (partlen-- > 0) {
-            char ch1 =  target .setIndex(  offset++ ) ;
-            char ch2 =  target .setIndex(  i++ ) ;
-            if (ch1 == ch2)
-                continue;
-            char uch1 = Character.toUpperCase(ch1);
-            char uch2 = Character.toUpperCase(ch2);
-            if (uch1 == uch2)
-                continue;
-            if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2))
-                return false;
-        }
-        return true;
-    }
-
-
-
-
-    // ================================================================
-
-    /**
-     * A regular expression.
-     * @serial
-     */
-    String regex;
-    /**
-     * @serial
-     */
-    int options;
-
-    /**
-     * The number of parenthesis in the regular expression.
-     * @serial
-     */
-    int nofparen;
-    /**
-     * Internal representation of the regular expression.
-     * @serial
-     */
-    Token tokentree;
-
-    boolean hasBackReferences = false;
-
-    transient int minlength;
-    transient Op operations = null;
-    transient int numberOfClosures;
-    transient Context context = null;
-    transient RangeToken firstChar = null;
-
-    transient String fixedString = null;
-    transient int fixedStringOptions;
-    transient BMPattern fixedStringTable = null;
-    transient boolean fixedStringOnly = false;
-
-
-    static final class Context {
-        CharacterIterator ciTarget;
-        String strTarget;
-        char[] charTarget;
-        int start;
-        int limit;
-        int length;
-        Match match;
-        boolean inuse = false;
-        int[] offsets;
-
-        Context() {
-        }
-
-        private void resetCommon(int nofclosures) {
-            this.length = this.limit-this.start;
-            this.inuse = true;
-            this.match = null;
-            if (this.offsets == null || this.offsets.length != nofclosures)
-                this.offsets = new int[nofclosures];
-            for (int i = 0;  i < nofclosures;  i ++)  this.offsets[i] = -1;
-        }
-        void reset(CharacterIterator target, int start, int limit, int nofclosures) {
-            this.ciTarget = target;
-            this.start = start;
-            this.limit = limit;
-            this.resetCommon(nofclosures);
-        }
-        void reset(String target, int start, int limit, int nofclosures) {
-            this.strTarget = target;
-            this.start = start;
-            this.limit = limit;
-            this.resetCommon(nofclosures);
-        }
-        void reset(char[] target, int start, int limit, int nofclosures) {
-            this.charTarget = target;
-            this.start = start;
-            this.limit = limit;
-            this.resetCommon(nofclosures);
-        }
-    }
-
-    /**
-     * Prepares for matching.  This method is called just before starting matching.
-     */
-    void prepare() {
-        if (Op.COUNT)  Op.nofinstances = 0;
-        this.compile(this.tokentree);
-        /*
-        if  (this.operations.type == Op.CLOSURE && this.operations.getChild().type == Op.DOT) { // .*
-            Op anchor = Op.createAnchor(isSet(this.options, SINGLE_LINE) ? 'A' : '@');
-            anchor.next = this.operations;
-            this.operations = anchor;
-        }
-        */
-        if (Op.COUNT)  System.err.println("DEBUG: The number of operations: "+Op.nofinstances);
-
-        this.minlength = this.tokentree.getMinLength();
-
-        this.firstChar = null;
-        if (!isSet(this.options, PROHIBIT_HEAD_CHARACTER_OPTIMIZATION)
-            && !isSet(this.options, XMLSCHEMA_MODE)) {
-            RangeToken firstChar = Token.createRange();
-            int fresult = this.tokentree.analyzeFirstCharacter(firstChar, this.options);
-            if (fresult == Token.FC_TERMINAL) {
-                firstChar.compactRanges();
-                this.firstChar = firstChar;
-                if (DEBUG)
-                    System.err.println("DEBUG: Use the first character optimization: "+firstChar);
-            }
-        }
-
-        if (this.operations != null
-            && (this.operations.type == Op.STRING || this.operations.type == Op.CHAR)
-            && this.operations.next == null) {
-            if (DEBUG)
-                System.err.print(" *** Only fixed string! *** ");
-            this.fixedStringOnly = true;
-            if (this.operations.type == Op.STRING)
-                this.fixedString = this.operations.getString();
-            else if (this.operations.getData() >= 0x10000) { // Op.CHAR
-                this.fixedString = REUtil.decomposeToSurrogates(this.operations.getData());
-            } else {
-                char[] ac = new char[1];
-                ac[0] = (char)this.operations.getData();
-                this.fixedString = new String(ac);
-            }
-            this.fixedStringOptions = this.options;
-            this.fixedStringTable = new BMPattern(this.fixedString, 256,
-                                                  isSet(this.fixedStringOptions, IGNORE_CASE));
-        } else if (!isSet(this.options, PROHIBIT_FIXED_STRING_OPTIMIZATION)
-                   && !isSet(this.options, XMLSCHEMA_MODE)) {
-            Token.FixedStringContainer container = new Token.FixedStringContainer();
-            this.tokentree.findFixedString(container, this.options);
-            this.fixedString = container.token == null ? null : container.token.getString();
-            this.fixedStringOptions = container.options;
-            if (this.fixedString != null && this.fixedString.length() < 2)
-                this.fixedString = null;
-            // This pattern has a fixed string of which length is more than one.
-            if (this.fixedString != null) {
-                this.fixedStringTable = new BMPattern(this.fixedString, 256,
-                                                      isSet(this.fixedStringOptions, IGNORE_CASE));
-                if (DEBUG) {
-                    System.err.println("DEBUG: The longest fixed string: "+this.fixedString.length()
-                                       +"/" //+this.fixedString
-                                       +"/"+REUtil.createOptionString(this.fixedStringOptions));
-                    System.err.print("String: ");
-                    REUtil.dumpString(this.fixedString);
-                }
-            }
-        }
-    }
-
-    /**
-     * An option.
-     * If you specify this option, <span class="REGEX"><kbd>(</kbd><var>X</var><kbd>)</kbd></span>
-     * captures matched text, and <span class="REGEX"><kbd>(:?</kbd><var>X</var><kbd>)</kbd></span>
-     * does not capture.
-     *
-     * @see #RegularExpression(java.lang.String,int)
-     * @see #setPattern(java.lang.String,int)
-    static final int MARK_PARENS = 1<<0;
-     */
-
-    /**
-     * "i"
-     */
-    static final int IGNORE_CASE = 1<<1;
-
-    /**
-     * "s"
-     */
-    static final int SINGLE_LINE = 1<<2;
-
-    /**
-     * "m"
-     */
-    static final int MULTIPLE_LINES = 1<<3;
-
-    /**
-     * "x"
-     */
-    static final int EXTENDED_COMMENT = 1<<4;
-
-    /**
-     * This option redefines <span class="REGEX"><kbd>\d \D \w \W \s \S</kbd></span>.
-     *
-     * @see #RegularExpression(java.lang.String,int)
-     * @see #setPattern(java.lang.String,int)
-     * @see #UNICODE_WORD_BOUNDARY
-     */
-    static final int USE_UNICODE_CATEGORY = 1<<5; // "u"
-
-    /**
-     * An option.
-     * This enables to process locale-independent word boundary for <span class="REGEX"><kbd>\b \B \&lt; \></kbd></span>.
-     * <p>By default, the engine considers a position between a word character
-     * (<span class="REGEX"><Kbd>\w</kbd></span>) and a non word character
-     * is a word boundary.
-     * <p>By this option, the engine checks word boundaries with the method of
-     * 'Unicode Regular Expression Guidelines' Revision 4.
-     *
-     * @see #RegularExpression(java.lang.String,int)
-     * @see #setPattern(java.lang.String,int)
-     */
-    static final int UNICODE_WORD_BOUNDARY = 1<<6; // "w"
-
-    /**
-     * "H"
-     */
-    static final int PROHIBIT_HEAD_CHARACTER_OPTIMIZATION = 1<<7;
-    /**
-     * "F"
-     */
-    static final int PROHIBIT_FIXED_STRING_OPTIMIZATION = 1<<8;
-    /**
-     * "X". XML Schema mode.
-     */
-    static final int XMLSCHEMA_MODE = 1<<9;
-    /**
-     * ",".
-     */
-    static final int SPECIAL_COMMA = 1<<10;
-
-
-    private static final boolean isSet(int options, int flag) {
-        return (options & flag) == flag;
-    }
-
-    /**
-     * Creates a new RegularExpression instance.
-     *
-     * @param regex A regular expression
-     * @exception org.apache.xerces.utils.regex.ParseException <VAR>regex</VAR> is not conforming to the syntax.
-     */
-    public RegularExpression(String regex) throws ParseException {
-        this.setPattern(regex, null);
-    }
-
-    /**
-     * Creates a new RegularExpression instance with options.
-     *
-     * @param regex A regular expression
-     * @param options A String consisted of "i" "m" "s" "u" "w" "," "X"
-     * @exception org.apache.xerces.utils.regex.ParseException <VAR>regex</VAR> is not conforming to the syntax.
-     */
-    public RegularExpression(String regex, String options) throws ParseException {
-        this.setPattern(regex, options);
-    }
-
-    RegularExpression(String regex, Token tok, int parens, boolean hasBackReferences, int options) {
-        this.regex = regex;
-        this.tokentree = tok;
-        this.nofparen = parens;
-        this.options = options;
-        this.hasBackReferences = hasBackReferences;
-    }
-
-    /**
-     *
-     */
-    public void setPattern(String newPattern) throws ParseException {
-        this.setPattern(newPattern, this.options);
-    }
-
-    private void setPattern(String newPattern, int options) throws ParseException {
-        this.regex = newPattern;
-        this.options = options;
-        RegexParser rp = this.isSet(this.options, RegularExpression.XMLSCHEMA_MODE)
-                         ? new ParserForXMLSchema() : new RegexParser();
-        this.tokentree = rp.parse(this.regex, this.options);
-        this.nofparen = rp.parennumber;
-        this.hasBackReferences = rp.hasBackReferences;
-
-        this.operations = null;
-        this.context = null;
-    }
-    /**
-     *
-     */
-    public void setPattern(String newPattern, String options) throws ParseException {
-        this.setPattern(newPattern, REUtil.parseOptions(options));
-    }
-
-    /**
-     *
-     */
-    public String getPattern() {
-        return this.regex;
-    }
-
-    /**
-     * Represents this instence in String.
-     */
-    public String toString() {
-        return this.tokentree.toString(this.options);
-    }
-
-    /**
-     * Returns a option string.
-     * The order of letters in it may be different from a string specified
-     * in a constructor or <code>setPattern()</code>.
-     *
-     * @see #RegularExpression(java.lang.String,java.lang.String)
-     * @see #setPattern(java.lang.String,java.lang.String)
-     */
-    public String getOptions() {
-        return REUtil.createOptionString(this.options);
-    }
-
-    /**
-     *  Return true if patterns are the same and the options are equivalent.
-     */
-    public boolean equals(Object obj) {
-        if (obj == null)  return false;
-        if (!(obj instanceof RegularExpression))
-            return false;
-        RegularExpression r = (RegularExpression)obj;
-        return this.regex.equals(r.regex) && this.options == r.options;
-    }
-
-    boolean equals(String pattern, int options) {
-        return this.regex.equals(pattern) && this.options == options;
-    }
-
-    /**
-     *
-     */
-    public int hashCode() {
-        return (this.regex+"/"+this.getOptions()).hashCode();
-    }
-
-    /**
-     * Return the number of regular expression groups.
-     * This method returns 1 when the regular expression has no capturing-parenthesis.
-     *
-     */
-    public int getNumberOfGroups() {
-        return this.nofparen;
-    }
-
-    // ================================================================
-
-    private static final int WT_IGNORE = 0;
-    private static final int WT_LETTER = 1;
-    private static final int WT_OTHER = 2;
-    transient static Token wordchar = null;
-    private static final int getWordType0(char ch, int opts) {
-        if (!isSet(opts, UNICODE_WORD_BOUNDARY)) {
-            if (isSet(opts, USE_UNICODE_CATEGORY)) {
-                if (RegularExpression.wordchar == null)
-                    RegularExpression.wordchar = Token.getRange("IsWord", true);
-                return RegularExpression.wordchar.match(ch) ? WT_LETTER : WT_OTHER;
-            }
-            return isWordChar(ch) ? WT_LETTER : WT_OTHER;
-        }
-
-        switch (Character.getType(ch)) {
-        case Character.UPPERCASE_LETTER:      // L
-        case Character.LOWERCASE_LETTER:      // L
-        case Character.TITLECASE_LETTER:      // L
-        case Character.MODIFIER_LETTER:       // L
-        case Character.OTHER_LETTER:          // L
-        case Character.LETTER_NUMBER:         // N
-        case Character.DECIMAL_DIGIT_NUMBER:  // N
-        case Character.OTHER_NUMBER:          // N
-        case Character.COMBINING_SPACING_MARK: // Mc
-            return WT_LETTER;
-
-        case Character.FORMAT:                // Cf
-        case Character.NON_SPACING_MARK:      // Mn
-        case Character.ENCLOSING_MARK:        // Mc
-            return WT_IGNORE;
-
-        case Character.CONTROL:               // Cc
-            switch (ch) {
-            case '\t':
-            case '\n':
-            case '\u000B':
-            case '\f':
-            case '\r':
-                return WT_OTHER;
-            default:
-                return WT_IGNORE;
-            }
-
-        default:
-            return WT_OTHER;
-        }
-    }
-
-    // ================================================================
-
-    static final int LINE_FEED = 0x000A;
-    static final int CARRIAGE_RETURN = 0x000D;
-    static final int LINE_SEPARATOR = 0x2028;
-    static final int PARAGRAPH_SEPARATOR = 0x2029;
-
-    private static final boolean isEOLChar(int ch) {
-        return ch == LINE_FEED || ch == CARRIAGE_RETURN || ch == LINE_SEPARATOR
-        || ch == PARAGRAPH_SEPARATOR;
-    }
-
-    private static final boolean isWordChar(int ch) { // Legacy word characters
-        if (ch == '_')  return true;
-        if (ch < '0')  return false;
-        if (ch > 'z')  return false;
-        if (ch <= '9')  return true;
-        if (ch < 'A')  return false;
-        if (ch <= 'Z')  return true;
-        if (ch < 'a')  return false;
-        return true;
-    }
-
-    private static final boolean matchIgnoreCase(int chardata, int ch) {
-        if (chardata == ch)  return true;
-        if (chardata > 0xffff || ch > 0xffff)  return false;
-        char uch1 = Character.toUpperCase((char)chardata);
-        char uch2 = Character.toUpperCase((char)ch);
-        if (uch1 == uch2)  return true;
-        return Character.toLowerCase(uch1) == Character.toLowerCase(uch2);
-    }
-}
diff --git a/src/org/apache/xerces/utils/regex/Token.java b/src/org/apache/xerces/utils/regex/Token.java
deleted file mode 100644
index d8010e1..0000000
--- a/src/org/apache/xerces/utils/regex/Token.java
+++ /dev/null
@@ -1,1421 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.utils.regex;
-
-import java.util.Vector;
-import java.util.Hashtable;
-
-/**
- * This class represents a node in parse tree.
- */
-class Token implements java.io.Serializable {
-    static final boolean COUNTTOKENS = true;
-    static int tokens = 0;
-
-    static final int CHAR = 0;                  // Literal char
-    static final int DOT = 11;                  // .
-    static final int CONCAT = 1;                // XY
-    static final int UNION = 2;                 // X|Y|Z
-    static final int CLOSURE = 3;               // X*
-    static final int RANGE = 4;                 // [a-zA-Z] etc.
-    static final int NRANGE = 5;                // [^a-zA-Z] etc.
-    static final int PAREN = 6;                 // (X) or (?:X)
-    static final int EMPTY = 7;                 //
-    static final int ANCHOR = 8;                // ^ $ \b \B \< \> \A \Z \z
-    static final int NONGREEDYCLOSURE = 9;      // *? +?
-    static final int STRING = 10;               // strings
-    static final int BACKREFERENCE = 12;        // back references
-    static final int LOOKAHEAD = 20;            // (?=...)
-    static final int NEGATIVELOOKAHEAD = 21;    // (?!...)
-    static final int LOOKBEHIND = 22;           // (?<=...)
-    static final int NEGATIVELOOKBEHIND = 23;   // (?<!...)
-    static final int INDEPENDENT = 24;          // (?>...)
-    static final int MODIFIERGROUP = 25;        // (?ims-ims:...)
-    static final int CONDITION = 26;            // (?(...)yes|no)
-
-    static final int UTF16_MAX = 0x10ffff;
-
-    int type;
-
-    static protected Token token_dot;
-    static protected Token token_0to9;
-    static protected Token token_wordchars;
-    static protected Token token_not_0to9;
-    static protected Token token_not_wordchars;
-    static protected Token token_spaces;
-    static protected Token token_not_spaces;
-    static protected Token token_empty;
-    static protected Token token_linebeginning;
-    static protected Token token_linebeginning2;
-    static protected Token token_lineend;
-    static protected Token token_stringbeginning;
-    static protected Token token_stringend;
-    static protected Token token_stringend2;
-    static protected Token token_wordedge;
-    static protected Token token_not_wordedge;
-    static protected Token token_wordbeginning;
-    static protected Token token_wordend;
-    static {
-        Token.token_empty = new Token(Token.EMPTY);
-
-        Token.token_linebeginning = Token.createAnchor('^');
-        Token.token_linebeginning2 = Token.createAnchor('@');
-        Token.token_lineend = Token.createAnchor('$');
-        Token.token_stringbeginning = Token.createAnchor('A');
-        Token.token_stringend = Token.createAnchor('z');
-        Token.token_stringend2 = Token.createAnchor('Z');
-        Token.token_wordedge = Token.createAnchor('b');
-        Token.token_not_wordedge = Token.createAnchor('B');
-        Token.token_wordbeginning = Token.createAnchor('<');
-        Token.token_wordend = Token.createAnchor('>');
-
-        Token.token_dot = new Token(Token.DOT);
-
-        Token.token_0to9 = Token.createRange();
-        Token.token_0to9.addRange('0', '9');
-        Token.token_wordchars = Token.createRange();
-        Token.token_wordchars.addRange('0', '9');
-        Token.token_wordchars.addRange('A', 'Z');
-        Token.token_wordchars.addRange('_', '_');
-        Token.token_wordchars.addRange('a', 'z');
-        Token.token_spaces = Token.createRange();
-        Token.token_spaces.addRange('\t', '\t');
-        Token.token_spaces.addRange('\n', '\n');
-        Token.token_spaces.addRange('\f', '\f');
-        Token.token_spaces.addRange('\r', '\r');
-        Token.token_spaces.addRange(' ', ' ');
-
-        Token.token_not_0to9 = Token.complementRanges(Token.token_0to9);
-        Token.token_not_wordchars = Token.complementRanges(Token.token_wordchars);
-        Token.token_not_spaces = Token.complementRanges(Token.token_spaces);
-    }
-
-    static Token.ParenToken createLook(int type, Token child) {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new Token.ParenToken(type, child, 0);
-    }
-    static Token.ParenToken createParen(Token child, int pnumber) {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new Token.ParenToken(Token.PAREN, child, pnumber);
-    }
-    static Token.ClosureToken createClosure(Token tok) {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new Token.ClosureToken(Token.CLOSURE, tok);
-    }
-    static Token.ClosureToken createNGClosure(Token tok) {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new Token.ClosureToken(Token.NONGREEDYCLOSURE, tok);
-    }
-    static Token.ConcatToken createConcat(Token tok1, Token tok2) {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new Token.ConcatToken(tok1, tok2);
-    }
-    static Token.UnionToken createConcat() {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new Token.UnionToken(Token.CONCAT); // *** It is not a bug.
-    }
-    static Token.UnionToken createUnion() {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new Token.UnionToken(Token.UNION);
-    }
-    static Token createEmpty() {
-        return Token.token_empty;
-    }
-    static RangeToken createRange() {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new RangeToken(Token.RANGE);
-    }
-    static RangeToken createNRange() {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new RangeToken(Token.NRANGE);
-    }
-    static Token.CharToken createChar(int ch) {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new Token.CharToken(Token.CHAR, ch);
-    }
-    static private Token.CharToken createAnchor(int ch) {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new Token.CharToken(Token.ANCHOR, ch);
-    }
-    static Token.StringToken createBackReference(int refno) {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new Token.StringToken(Token.BACKREFERENCE, null, refno);
-    }
-    static Token.StringToken createString(String str) {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new Token.StringToken(Token.STRING, str, 0);
-    }
-    static Token.ModifierToken createModifierGroup(Token child, int add, int mask) {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new Token.ModifierToken(child, add, mask);
-    }
-    static Token.ConditionToken createCondition(int refno, Token condition,
-                                                Token yespat, Token nopat) {
-        if (COUNTTOKENS)  Token.tokens ++;
-        return new Token.ConditionToken(refno, condition, yespat, nopat);
-    }
-
-    protected Token(int type) {
-        this.type = type;
-    }
-
-    /**
-     * A number of children.
-     */
-    int size() {
-        return 0;
-    }
-    Token getChild(int index) {
-        return null;
-    }
-    void addChild(Token tok) {
-        throw new RuntimeException("Not supported.");
-    }
-
-                                                // for RANGE or NRANGE
-    protected void addRange(int start, int end) {
-        throw new RuntimeException("Not supported.");
-    }
-    protected void sortRanges() {
-        throw new RuntimeException("Not supported.");
-    }
-    protected void compactRanges() {
-        throw new RuntimeException("Not supported.");
-    }
-    protected void mergeRanges(Token tok) {
-        throw new RuntimeException("Not supported.");
-    }
-    protected void subtractRanges(Token tok) {
-        throw new RuntimeException("Not supported.");
-    }
-    protected void intersectRanges(Token tok) {
-        throw new RuntimeException("Not supported.");
-    }
-    static Token complementRanges(Token tok) {
-        return RangeToken.complementRanges(tok);
-    }
-
-
-    void setMin(int min) {                      // for CLOSURE
-    }
-    void setMax(int max) {                      // for CLOSURE
-    }
-    int getMin() {                              // for CLOSURE
-        return -1;
-    }
-    int getMax() {                              // for CLOSURE
-        return -1;
-    }
-    int getReferenceNumber() {                  // for STRING
-        return 0;
-    }
-    String getString() {                        // for STRING
-        return null;
-    }
-
-    int getParenNumber() {
-        return 0;
-    }
-    int getChar() {
-        return -1;
-    }
-
-    public String toString() {
-        return this.toString(0);
-    }
-    public String toString(int options) {
-        return this.type == Token.DOT ? "." : "";
-    }
-
-    /**
-     * How many characters are needed?
-     */
-    final int getMinLength() {
-        switch (this.type) {
-          case CONCAT:
-            int sum = 0;
-            for (int i = 0;  i < this.size();  i ++)
-                sum += this.getChild(i).getMinLength();
-            return sum;
-
-          case CONDITION:
-          case UNION:
-            if (this.size() == 0)
-                return 0;
-            int ret = this.getChild(0).getMinLength();
-            for (int i = 1;  i < this.size();  i ++) {
-                int min = this.getChild(i).getMinLength();
-                if (min < ret)  ret = min;
-            }
-            return ret;
-
-          case CLOSURE:
-          case NONGREEDYCLOSURE:
-            if (this.getMin() >= 0)
-                return this.getMin() * this.getChild(0).getMinLength();
-            return 0;
-
-          case EMPTY:
-          case ANCHOR:
-            return 0;
-
-          case DOT:
-          case CHAR:
-          case RANGE:
-          case NRANGE:
-            return 1;
-
-          case INDEPENDENT:
-          case PAREN:
-          case MODIFIERGROUP:
-            return this.getChild(0).getMinLength();
-
-          case BACKREFERENCE:
-            return 0;                           // *******
-
-          case STRING:
-            return this.getString().length();
-
-          case LOOKAHEAD:
-          case NEGATIVELOOKAHEAD:
-          case LOOKBEHIND:
-          case NEGATIVELOOKBEHIND:
-            return 0;                           // ***** Really?
-
-          default:
-            throw new RuntimeException("Token#getMinLength(): Invalid Type: "+this.type);
-        }
-    }
-
-    final int getMaxLength() {
-        switch (this.type) {
-          case CONCAT:
-            int sum = 0;
-            for (int i = 0;  i < this.size();  i ++) {
-                int d = this.getChild(i).getMaxLength();
-                if (d < 0)  return -1;
-                sum += d;
-            }
-            return sum;
-
-          case CONDITION:
-          case UNION:
-            if (this.size() == 0)
-                return 0;
-            int ret = this.getChild(0).getMaxLength();
-            for (int i = 1;  ret >= 0 && i < this.size();  i ++) {
-                int max = this.getChild(i).getMaxLength();
-                if (max < 0) {                  // infinity
-                    ret = -1;
-                    break;
-                }
-                if (max > ret)  ret = max;
-            }
-            return ret;
-
-          case CLOSURE:
-          case NONGREEDYCLOSURE:
-            if (this.getMax() >= 0)
-                                                // When this.child.getMaxLength() < 0,
-                                                // this returns minus value
-                return this.getMax() * this.getChild(0).getMaxLength();
-            return -1;
-
-          case EMPTY:
-          case ANCHOR:
-            return 0;
-
-          case CHAR:
-            return 1;
-          case DOT:
-          case RANGE:
-          case NRANGE:
-            return 2;
-
-          case INDEPENDENT:
-          case PAREN:
-          case MODIFIERGROUP:
-            return this.getChild(0).getMaxLength();
-
-          case BACKREFERENCE:
-            return -1;                          // ******
-
-          case STRING:
-            return this.getString().length();
-
-          case LOOKAHEAD:
-          case NEGATIVELOOKAHEAD:
-          case LOOKBEHIND:
-          case NEGATIVELOOKBEHIND:
-            return 0;                           // ***** Really?
-
-          default:
-            throw new RuntimeException("Token#getMaxLength(): Invalid Type: "+this.type);
-        }
-    }
-
-    static final int FC_CONTINUE = 0;
-    static final int FC_TERMINAL = 1;
-    static final int FC_ANY = 2;
-    private static final boolean isSet(int options, int flag) {
-        return (options & flag) == flag;
-    }
-    final int analyzeFirstCharacter(RangeToken result, int options) {
-        switch (this.type) {
-          case CONCAT:
-            int ret = FC_CONTINUE;
-            for (int i = 0;  i < this.size();  i ++)
-                if ((ret = this.getChild(i).analyzeFirstCharacter(result, options)) != FC_CONTINUE)
-                    break;
-            return ret;
-
-          case UNION:
-            if (this.size() == 0)
-                return FC_CONTINUE;
-            /*
-             *  a|b|c -> FC_TERMINAL
-             *  a|.|c -> FC_ANY
-             *  a|b|  -> FC_CONTINUE
-             */
-            int ret2 = FC_CONTINUE;
-            boolean hasEmpty = false;
-            for (int i = 0;  i < this.size();  i ++) {
-                ret2 = this.getChild(i).analyzeFirstCharacter(result, options);
-                if (ret2 == FC_ANY)
-                    break;
-                else if (ret2 == FC_CONTINUE)
-                    hasEmpty = true;
-            }
-            return hasEmpty ? FC_CONTINUE : ret2;
-
-          case CONDITION:
-            int ret3 = this.getChild(0).analyzeFirstCharacter(result, options);
-            if (this.size() == 1)  return FC_CONTINUE;
-            if (ret3 == FC_ANY)  return ret3;
-            int ret4 = this.getChild(1).analyzeFirstCharacter(result, options);
-            if (ret4 == FC_ANY)  return ret4;
-            return ret3 == FC_CONTINUE || ret4 == FC_CONTINUE ? FC_CONTINUE : FC_TERMINAL;
-
-          case CLOSURE:
-          case NONGREEDYCLOSURE:
-            this.getChild(0).analyzeFirstCharacter(result, options);
-            return FC_CONTINUE;
-
-          case EMPTY:
-          case ANCHOR:
-            return FC_CONTINUE;
-
-          case CHAR:
-            int ch = this.getChar();
-            result.addRange(ch, ch);
-            if (ch < 0x10000 && isSet(options, RegularExpression.IGNORE_CASE)) {
-                ch = Character.toUpperCase((char)ch);
-                result.addRange(ch, ch);
-                ch = Character.toLowerCase((char)ch);
-                result.addRange(ch, ch);
-            }
-            return FC_TERMINAL;
-
-          case DOT:                             // ****
-            if (isSet(options, RegularExpression.SINGLE_LINE)) {
-                return FC_CONTINUE;             // **** We can not optimize.
-            } else {
-                return FC_CONTINUE;
-                /*
-                result.addRange(0, RegularExpression.LINE_FEED-1);
-                result.addRange(RegularExpression.LINE_FEED+1, RegularExpression.CARRIAGE_RETURN-1);
-                result.addRange(RegularExpression.CARRIAGE_RETURN+1,
-                                RegularExpression.LINE_SEPARATOR-1);
-                result.addRange(RegularExpression.PARAGRAPH_SEPARATOR+1, UTF16_MAX);
-                return 1;
-                */
-            }
-
-          case RANGE:
-            if (isSet(options, RegularExpression.IGNORE_CASE)) {
-                result.mergeRanges(((RangeToken)this).getCaseInsensitiveToken());
-            } else {
-                result.mergeRanges(this);
-            }
-            return FC_TERMINAL;
-
-          case NRANGE:                          // ****
-            if (isSet(options, RegularExpression.IGNORE_CASE)) {
-                result.mergeRanges(Token.complementRanges(((RangeToken)this).getCaseInsensitiveToken()));
-            } else {
-                result.mergeRanges(Token.complementRanges(this));
-            }
-            return FC_TERMINAL;
-
-          case INDEPENDENT:
-          case PAREN:
-            return this.getChild(0).analyzeFirstCharacter(result, options);
-
-          case MODIFIERGROUP:
-            options |= ((ModifierToken)this).getOptions();
-            options &= ~((ModifierToken)this).getOptionsMask();
-            return this.getChild(0).analyzeFirstCharacter(result, options);
-
-          case BACKREFERENCE:
-            result.addRange(0, UTF16_MAX);  // **** We can not optimize.
-            return FC_ANY;
-
-          case STRING:
-            int cha = this.getString().charAt(0);
-            int ch2;
-            if (REUtil.isHighSurrogate(cha)
-                && this.getString().length() >= 2
-                && REUtil.isLowSurrogate((ch2 = this.getString().charAt(1))))
-                cha = REUtil.composeFromSurrogates(cha, ch2);
-            result.addRange(cha, cha);
-            if (cha < 0x10000 && isSet(options, RegularExpression.IGNORE_CASE)) {
-                cha = Character.toUpperCase((char)cha);
-                result.addRange(cha, cha);
-                cha = Character.toLowerCase((char)cha);
-                result.addRange(cha, cha);
-            }
-            return FC_TERMINAL;
-
-          case LOOKAHEAD:
-          case NEGATIVELOOKAHEAD:
-          case LOOKBEHIND:
-          case NEGATIVELOOKBEHIND:
-            return FC_CONTINUE;
-
-          default:
-            throw new RuntimeException("Token#analyzeHeadCharacter(): Invalid Type: "+this.type);
-        }
-    }
-
-    private final boolean isShorterThan(Token tok) {
-        if (tok == null)  return false;
-        /*
-        int mylength;
-        if (this.type == STRING)  mylength = this.getString().length();
-        else if (this.type == CHAR)  mylength = this.getChar() >= 0x10000 ? 2 : 1;
-        else throw new RuntimeException("Internal Error: Illegal type: "+this.type);
-        int otherlength;
-        if (tok.type == STRING)  otherlength = tok.getString().length();
-        else if (tok.type == CHAR)  otherlength = tok.getChar() >= 0x10000 ? 2 : 1;
-        else throw new RuntimeException("Internal Error: Illegal type: "+tok.type);
-        */
-        int mylength;
-        if (this.type == STRING)  mylength = this.getString().length();
-        else throw new RuntimeException("Internal Error: Illegal type: "+this.type);
-        int otherlength;
-        if (tok.type == STRING)  otherlength = tok.getString().length();
-        else throw new RuntimeException("Internal Error: Illegal type: "+tok.type);
-        return mylength < otherlength;
-    }
-
-    static class FixedStringContainer {
-        Token token = null;
-        int options = 0;
-        FixedStringContainer() {
-        }
-    }
-
-    final void findFixedString(FixedStringContainer container, int options) {
-        switch (this.type) {
-          case CONCAT:
-            Token prevToken = null;
-            int prevOptions = 0;
-            for (int i = 0;  i < this.size();  i ++) {
-                this.getChild(i).findFixedString(container, options);
-                if (prevToken == null || prevToken.isShorterThan(container.token)) {
-                    prevToken = container.token;
-                    prevOptions = container.options;
-                }
-            }
-            container.token = prevToken;
-            container.options = prevOptions;
-            return;
-
-          case UNION:
-          case CLOSURE:
-          case NONGREEDYCLOSURE:
-          case EMPTY:
-          case ANCHOR:
-          case RANGE:
-          case DOT:
-          case NRANGE:
-          case BACKREFERENCE:
-          case LOOKAHEAD:
-          case NEGATIVELOOKAHEAD:
-          case LOOKBEHIND:
-          case NEGATIVELOOKBEHIND:
-          case CONDITION:
-            container.token = null;
-            return;
-
-          case CHAR:                            // Ignore CHAR tokens.
-            container.token = null;             // **
-            return;                             // **
-
-          case STRING:
-            container.token = this;
-            container.options = options;
-            return;
-
-          case INDEPENDENT:
-          case PAREN:
-            this.getChild(0).findFixedString(container, options);
-            return;
-
-          case MODIFIERGROUP:
-            options |= ((ModifierToken)this).getOptions();
-            options &= ~((ModifierToken)this).getOptionsMask();
-            this.getChild(0).findFixedString(container, options);
-            return;
-
-          default:
-            throw new RuntimeException("Token#findFixedString(): Invalid Type: "+this.type);
-        }
-    }
-
-    boolean match(int ch) {
-        throw new RuntimeException("NFAArrow#match(): Internal error: "+this.type);
-    }
-
-    // ------------------------------------------------------
-    static protected Hashtable categories = new Hashtable();
-    static protected Hashtable categories2 = null;
-    static final String[] categoryNames = {
-        "Cn", "Lu", "Ll", "Lt", "Lm", "Lo", "Mn", "Me", "Mc", "Nd",
-        "Nl", "No", "Zs", "Zl", "Zp", "Cc", "Cf", null, "Co", "Cs",
-        "Pd", "Ps", "Pe", "Pc", "Po", "Sm", "Sc", "Sk", "So", // 28
-        "L", "M", "N", "Z", "C", "P", "S",      // 29-35
-    };
-    static final int CHAR_LETTER = 29;
-    static final int CHAR_MARK = 30;
-    static final int CHAR_NUMBER = 31;
-    static final int CHAR_SEPARATOR = 32;
-    static final int CHAR_OTHER = 33;
-    static final int CHAR_PUNCTUATION = 34;
-    static final int CHAR_SYMBOL = 35;
-    static final String[] blockNames = {
-        "Basic Latin",                          // 0
-        "Latin-1 Supplement",
-        "Latin Extended-A",
-        "Latin Extended-B",
-        "IPA Extensions",
-        "Spacing Modifier Letters",
-        "Combining Diacritical Marks",
-        "Greek",
-        "Cyrillic",                             // 8
-        "Armenian",
-        "Hebrew",
-        "Arabic",
-        "Devanagari",
-        "Bengali",
-        "Gurmukhi",
-        "Gujarati",
-        "Oriya",                                // 16
-        "Tamil",
-        "Telugu",
-        "Kannada",
-        "Malayalam",
-        "Thai",
-        "Lao",
-        "Tibetan",
-        "Georgian",                             // 24
-        "Hangul Jamo",
-        "Latin Extended Additional",
-        "Greek Extended",
-        "General Punctuation",
-        "Superscripts and Subscripts",
-        "Currency Symbols",
-        "Combining Marks for Symbols",
-        "Letterlike Symbols",                   // 32
-        "Number Forms",
-        "Arrows",
-        "Mathematical Operators",
-        "Miscellaneous Technical",
-        "Control Pictures",
-        "Optical Character Recognition",
-        "Enclosed Alphanumerics",
-        "Box Drawing",                          // 40
-        "Block Elements",
-        "Geometric Shapes",
-        "Miscellaneous Symbols",
-        "Dingbats",
-        "CJK Symbols and Punctuation",
-        "Hiragana",
-        "Katakana",
-        "Bopomofo",                             // 48
-        "Hangul Compatibility Jamo",
-        "Kanbun",
-        "Enclosed CJK Letters and Months",
-        "CJK Compatibility",
-        "CJK Unified Ideographs",
-        "Hangul Syllables",
-        "High Surrogates",
-        "High Private Use Surrogates",          // 56
-        "Low Surrogates",
-        "Private Use",
-        "CJK Compatibility Ideographs",
-        "Alphabetic Presentation Forms",
-        "Arabic Presentation Forms-A",
-        "Combining Half Marks",
-        "CJK Compatibility Forms",
-        "Small Form Variants",                  // 64
-        "Arabic Presentation Forms-B",
-        "Specials",
-        "Halfwidth and Fullwidth Forms",        // 67
-    };
-    static final String blockRanges =
-    "\u0000\u007F\u0080\u00FF\u0100\u017F\u0180\u024F\u0250\u02AF\u02B0\u02FF"
-    +"\u0300\u036F\u0370\u03FF\u0400\u04FF\u0530\u058F\u0590\u05FF\u0600\u06FF"
-    +"\u0900\u097F\u0980\u09FF\u0A00\u0A7F\u0A80\u0AFF\u0B00\u0B7F\u0B80\u0BFF"
-    +"\u0C00\u0C7F\u0C80\u0CFF\u0D00\u0D7F\u0E00\u0E7F\u0E80\u0EFF\u0F00\u0FBF"
-    +"\u10A0\u10FF\u1100\u11FF\u1E00\u1EFF\u1F00\u1FFF\u2000\u206F\u2070\u209F"
-    +"\u20A0\u20CF\u20D0\u20FF\u2100\u214F\u2150\u218F\u2190\u21FF\u2200\u22FF"
-    +"\u2300\u23FF\u2400\u243F\u2440\u245F\u2460\u24FF\u2500\u257F\u2580\u259F"
-    +"\u25A0\u25FF\u2600\u26FF\u2700\u27BF\u3000\u303F\u3040\u309F\u30A0\u30FF"
-    +"\u3100\u312F\u3130\u318F\u3190\u319F\u3200\u32FF\u3300\u33FF\u4E00\u9FFF"
-    +"\uAC00\uD7A3\uD800\uDB7F\uDB80\uDBFF\uDC00\uDFFF\uE000\uF8FF\uF900\uFAFF"
-    +"\uFB00\uFB4F\uFB50\uFDFF\uFE20\uFE2F\uFE30\uFE4F\uFE50\uFE6F\uFE70\uFEFE"
-    +"\uFEFF\uFEFF\uFF00\uFFEF";
-
-    static protected RangeToken getRange(String name, boolean positive) {
-        if (Token.categories.size() == 0) {
-            synchronized (Token.categories) {
-                Token[] ranges = new Token[Token.categoryNames.length];
-                for (int i = 0;  i < ranges.length;  i ++) {
-                    ranges[i] = Token.createRange();
-                }
-                for (int i = 0;  i < 0x10000;  i ++) {
-                    int type = Character.getType((char)i);
-                    ranges[type].addRange(i, i);
-                    switch (type) {
-                      case Character.UPPERCASE_LETTER:
-                      case Character.LOWERCASE_LETTER:
-                      case Character.TITLECASE_LETTER:
-                      case Character.MODIFIER_LETTER:
-                      case Character.OTHER_LETTER:
-                        type = CHAR_LETTER;
-                        break;
-                      case Character.NON_SPACING_MARK:
-                      case Character.COMBINING_SPACING_MARK:
-                      case Character.ENCLOSING_MARK:
-                        type = CHAR_MARK;
-                        break;
-                      case Character.DECIMAL_DIGIT_NUMBER:
-                      case Character.LETTER_NUMBER:
-                      case Character.OTHER_NUMBER:
-                        type = CHAR_NUMBER;
-                        break;
-                      case Character.SPACE_SEPARATOR:
-                      case Character.LINE_SEPARATOR:
-                      case Character.PARAGRAPH_SEPARATOR:
-                        type = CHAR_SEPARATOR;
-                        break;
-                      case Character.CONTROL:
-                      case Character.FORMAT:
-                      case Character.SURROGATE:
-                      case Character.PRIVATE_USE:
-                      case Character.UNASSIGNED:
-                        type = CHAR_OTHER;
-                        break;
-                      case Character.CONNECTOR_PUNCTUATION:
-                      case Character.DASH_PUNCTUATION:
-                      case Character.START_PUNCTUATION:
-                      case Character.END_PUNCTUATION:
-                      case Character.OTHER_PUNCTUATION:
-                        type = CHAR_PUNCTUATION;
-                        break;
-                      case Character.MATH_SYMBOL:
-                      case Character.CURRENCY_SYMBOL:
-                      case Character.MODIFIER_SYMBOL:
-                      case Character.OTHER_SYMBOL:
-                        type = CHAR_SYMBOL;
-                        break;
-                      default:
-                        throw new RuntimeException("org.apache.xerces.utils.regex.Token#getRange(): Unknown Unicode category: "+type);
-                    }
-                    ranges[type].addRange(i, i);
-                } // for all characters
-                ranges[Character.UNASSIGNED].addRange(0x10000, Token.UTF16_MAX);
-
-                Token.categories2 = new Hashtable();
-                for (int i = 0;  i < ranges.length;  i ++) {
-                    if (Token.categoryNames[i] != null) {
-                        if (i == Character.UNASSIGNED) { // Unassigned
-                            ranges[i].addRange(0x10000, Token.UTF16_MAX);
-                        }
-                        Token.categories.put(Token.categoryNames[i], ranges[i]);
-                        Token.categories2.put(Token.categoryNames[i],
-                                              Token.complementRanges(ranges[i]));
-                    }
-                }
-                for (int i = 0;  i < Token.blockNames.length;  i ++) {
-                    Token r1 = Token.createRange();
-                    int rstart = Token.blockRanges.charAt(i*2);
-                    int rend = Token.blockRanges.charAt(i*2+1);
-                    String n = Token.blockNames[i];
-                    r1.addRange(rstart, rend);
-                    if (n.equals("Specials"))
-                        r1.addRange(0xfff0, 0xfffd);
-                    Token.categories.put(n, r1);
-                    Token.categories2.put(n, Token.complementRanges(r1));
-                    if (n.indexOf(' ') >= 0) {
-                        StringBuffer buffer = new StringBuffer(n.length()+2);
-                        buffer.append("Is");
-                        for (int ci = 0;  ci < n.length();  ci ++)
-                            if (n.charAt(ci) != ' ')  buffer.append((char)n.charAt(ci));
-                        Token.setAlias(new String(buffer), n, true);
-                    }
-                }
-
-                                                // TR#18 1.2
-                Token.setAlias("ASSIGNED", "Cn", false);
-                Token.setAlias("UNASSIGNED", "Cn", true);
-                Token all = Token.createRange();
-                all.addRange(0, Token.UTF16_MAX);
-                Token.categories.put("ALL", all);
-                Token.categories2.put("ALL", Token.complementRanges(all));
-
-                Token isalpha = Token.createRange();
-                isalpha.mergeRanges(ranges[Character.UPPERCASE_LETTER]); // Lu
-                isalpha.mergeRanges(ranges[Character.LOWERCASE_LETTER]); // Ll
-                isalpha.mergeRanges(ranges[Character.OTHER_LETTER]); // Lo
-                Token.categories.put("IsAlpha", isalpha);
-                Token.categories2.put("IsAlpha", Token.complementRanges(isalpha));
-
-                Token isalnum = Token.createRange();
-                isalnum.mergeRanges(isalpha);   // Lu Ll Lo
-                isalnum.mergeRanges(ranges[Character.DECIMAL_DIGIT_NUMBER]); // Nd
-                Token.categories.put("IsAlnum", isalnum);
-                Token.categories2.put("IsAlnum", Token.complementRanges(isalnum));
-
-                Token isspace = Token.createRange();
-                isspace.mergeRanges(Token.token_spaces);
-                isspace.mergeRanges(ranges[CHAR_SEPARATOR]); // Z
-                Token.categories.put("IsSpace", isspace);
-                Token.categories2.put("IsSpace", Token.complementRanges(isspace));
-
-                Token isword = Token.createRange();
-                isword.mergeRanges(isalnum);     // Lu Ll Lo Nd
-                isword.addRange('_', '_');
-                Token.categories.put("IsWord", isword);
-                Token.categories2.put("IsWord", Token.complementRanges(isword));
-
-                Token isascii = Token.createRange();
-                isascii.addRange(0, 127);
-                Token.categories.put("IsASCII", isascii);
-                Token.categories2.put("IsASCII", Token.complementRanges(isascii));
-
-                Token isnotgraph = Token.createRange();
-                isnotgraph.mergeRanges(ranges[CHAR_OTHER]);
-                isnotgraph.addRange(' ', ' ');
-                Token.categories.put("IsGraph", Token.complementRanges(isnotgraph));
-                Token.categories2.put("IsGraph", isnotgraph);
-
-                Token isxdigit = Token.createRange();
-                isxdigit.addRange('0', '9');
-                isxdigit.addRange('A', 'F');
-                isxdigit.addRange('a', 'f');
-                Token.categories.put("IsXDigit", Token.complementRanges(isxdigit));
-                Token.categories2.put("IsXDigit", isxdigit);
-                
-                Token.setAlias("IsDigit", "Nd", true);
-                Token.setAlias("IsUpper", "Lu", true);
-                Token.setAlias("IsLower", "Ll", true);
-                Token.setAlias("IsCntrl", "C", true);
-                Token.setAlias("IsPrint", "C", false);
-                Token.setAlias("IsPunct", "P", true);
-
-                Token.setAlias("alpha", "IsAlpha", true);
-                Token.setAlias("alnum", "IsAlnum", true);
-                Token.setAlias("ascii", "IsASCII", true);
-                Token.setAlias("cntrl", "IsCntrl", true);
-                Token.setAlias("digit", "IsDigit", true);
-                Token.setAlias("graph", "IsGraph", true);
-                Token.setAlias("lower", "IsLower", true);
-                Token.setAlias("print", "IsPrint", true);
-                Token.setAlias("punct", "IsPunct", true);
-                Token.setAlias("space", "IsSpace", true);
-                Token.setAlias("upper", "IsUpper", true);
-                Token.setAlias("word", "IsWord", true); // Perl extension
-                Token.setAlias("xdigit", "IsXDigit", true);
-
-            } // synchronized
-        } // if null
-        RangeToken tok = positive ? (RangeToken)Token.categories.get(name)
-            : (RangeToken)Token.categories2.get(name);
-        return tok;
-    }
-
-    private static void setAlias(String newName, String name, boolean positive) {
-        Token t1 = (Token)Token.categories.get(name);
-        Token t2 = (Token)Token.categories2.get(name);
-        if (positive) {
-            Token.categories.put(newName, t1);
-            Token.categories2.put(newName, t2);
-        } else {
-            Token.categories2.put(newName, t1);
-            Token.categories.put(newName, t2);
-        }
-    }
-
-    // ------------------------------------------------------
-
-    static final String viramaString =
-    "\u094D"// ;DEVANAGARI SIGN VIRAMA;Mn;9;ON;;;;;N;;;;;
-    +"\u09CD"//;BENGALI SIGN VIRAMA;Mn;9;ON;;;;;N;;;;;
-    +"\u0A4D"//;GURMUKHI SIGN VIRAMA;Mn;9;ON;;;;;N;;;;;
-    +"\u0ACD"//;GUJARATI SIGN VIRAMA;Mn;9;ON;;;;;N;;;;;
-    +"\u0B4D"//;ORIYA SIGN VIRAMA;Mn;9;ON;;;;;N;;;;;
-    +"\u0BCD"//;TAMIL SIGN VIRAMA;Mn;9;ON;;;;;N;;;;;
-    +"\u0C4D"//;TELUGU SIGN VIRAMA;Mn;9;ON;;;;;N;;;;;
-    +"\u0CCD"//;KANNADA SIGN VIRAMA;Mn;9;ON;;;;;N;;;;;
-    +"\u0D4D"//;MALAYALAM SIGN VIRAMA;Mn;9;ON;;;;;N;;;;;
-    +"\u0E3A"//;THAI CHARACTER PHINTHU;Mn;9;ON;;;;;N;THAI VOWEL SIGN PHINTHU;;;;
-    +"\u0F84";//;TIBETAN MARK HALANTA;Mn;9;ON;;;;;N;TIBETAN VIRAMA;;;;
-
-    static private Token token_grapheme = null;
-    static synchronized protected Token getGraphemePattern() {
-        if (Token.token_grapheme != null)
-            return Token.token_grapheme;
-
-        Token base_char = Token.createRange();  // [{ASSIGNED}]-[{M},{C}]
-        base_char.mergeRanges(Token.getRange("ASSIGNED", true));
-        base_char.subtractRanges(Token.getRange("M", true));
-        base_char.subtractRanges(Token.getRange("C", true));
-
-        Token virama = Token.createRange();
-        for (int i = 0;  i < Token.viramaString.length();  i ++) {
-            int ch = viramaString.charAt(i);
-            virama.addRange(i, i);
-        }
-
-        Token combiner_wo_virama = Token.createRange();
-        combiner_wo_virama.mergeRanges(Token.getRange("M", true));
-        combiner_wo_virama.addRange(0x1160, 0x11ff); // hangul_medial and hangul_final
-        combiner_wo_virama.addRange(0xff9e, 0xff9f); // extras
-
-        Token left = Token.createUnion();       // base_char?
-        left.addChild(base_char);
-        left.addChild(Token.token_empty);
-
-        Token foo = Token.createUnion();
-        foo.addChild(Token.createConcat(virama, Token.getRange("L", true)));
-        foo.addChild(combiner_wo_virama);
-
-        foo = Token.createClosure(foo);
-
-        foo = Token.createConcat(left, foo);
-
-        Token.token_grapheme = foo;
-        return Token.token_grapheme;
-    }
-
-    /**
-     * Combing Character Sequence in Perl 5.6.
-     */
-    static private Token token_ccs = null;
-    static synchronized protected Token getCombiningCharacterSequence() {
-        if (Token.token_ccs != null)
-            return Token.token_ccs;
-
-        Token foo = Token.createClosure(Token.getRange("M", true)); // \pM*
-        foo = Token.createConcat(Token.getRange("M", false), foo); // \PM + \pM*
-        Token.token_ccs = foo;
-        return Token.token_ccs;
-    }
-
-    // ------------------------------------------------------
-
-    // ------------------------------------------------------
-    /**
-     * This class represents a node in parse tree.
-     */
-    static class StringToken extends Token implements java.io.Serializable {
-        String string;
-        int refNumber;
-
-        StringToken(int type, String str, int n) {
-            super(type);
-            this.string = str;
-            this.refNumber = n;
-        }
-
-        int getReferenceNumber() {              // for STRING
-            return this.refNumber;
-        }
-        String getString() {                    // for STRING
-            return this.string;
-        }
-        
-        public String toString(int options) {
-            if (this.type == BACKREFERENCE)
-                return "\\"+this.refNumber;
-            else
-                return REUtil.quoteMeta(this.string);
-        }
-    }
-
-    /**
-     * This class represents a node in parse tree.
-     */
-    static class ConcatToken extends Token implements java.io.Serializable {
-        Token child;
-        Token child2;
-        
-        ConcatToken(Token t1, Token t2) {
-            super(Token.CONCAT);
-            this.child = t1;
-            this.child2 = t2;
-        }
-
-        int size() {
-            return 2;
-        }
-        Token getChild(int index) {
-            return index == 0 ? this.child : this.child2;
-        }
-
-        public String toString(int options) {
-            String ret;
-            if (this.child2.type == CLOSURE && this.child2.getChild(0) == this.child) {
-                ret = this.child.toString(options)+"+";
-            } else if (this.child2.type == NONGREEDYCLOSURE && this.child2.getChild(0) == this.child) {
-                ret = this.child.toString(options)+"+?";
-            } else
-                ret = this.child.toString(options)+this.child2.toString(options);
-            return ret;
-        }
-    }
-
-    /**
-     * This class represents a node in parse tree.
-     */
-    static class CharToken extends Token implements java.io.Serializable {
-        int chardata;
-
-        CharToken(int type, int ch) {
-            super(type);
-            this.chardata = ch;
-        }
-
-        int getChar() {
-            return this.chardata;
-        }
-
-        public String toString(int options) {
-            String ret;
-            switch (this.type) {
-              case CHAR:
-                switch (this.chardata) {
-                  case '|':  case '*':  case '+':  case '?':
-                  case '(':  case ')':  case '.':  case '[':
-                  case '{':  case '\\':
-                    ret = "\\"+(char)this.chardata;
-                    break;
-                  case '\f':  ret = "\\f";  break;
-                  case '\n':  ret = "\\n";  break;
-                  case '\r':  ret = "\\r";  break;
-                  case '\t':  ret = "\\t";  break;
-                  case 0x1b:  ret = "\\e";  break;
-                    //case 0x0b:  ret = "\\v";  break;
-                  default:
-                    if (this.chardata >= 0x10000) {
-                        String pre = "0"+Integer.toHexString(this.chardata);
-                        ret = "\\v"+pre.substring(pre.length()-6, pre.length());
-                    } else
-                        ret = ""+(char)this.chardata;
-                }
-                break;
-
-              case ANCHOR:
-                if (this == Token.token_linebeginning || this == Token.token_lineend)
-                    ret = ""+(char)this.chardata;
-                else 
-                    ret = "\\"+(char)this.chardata;
-                break;
-
-              default:
-                ret = null;
-            }
-            return ret;
-        }
-
-        boolean match(int ch) {
-            if (this.type == CHAR) {
-                return ch == this.chardata;
-            } else
-                throw new RuntimeException("NFAArrow#match(): Internal error: "+this.type);
-        }
-    }
-
-    /**
-     * This class represents a node in parse tree.
-     */
-    static class ClosureToken extends Token implements java.io.Serializable {
-        int min;
-        int max;
-        Token child;
-
-        ClosureToken(int type, Token tok) {
-            super(type);
-            this.child = tok;
-            this.setMin(-1);
-            this.setMax(-1);
-        }
-
-        int size() {
-            return 1;
-        }
-        Token getChild(int index) {
-            return this.child;
-        }
-
-        final void setMin(int min) {
-            this.min = min;
-        }
-        final void setMax(int max) {
-            this.max = max;
-        }
-        final int getMin() {
-            return this.min;
-        }
-        final int getMax() {
-            return this.max;
-        }
-
-        public String toString(int options) {
-            String ret;
-            if (this.type == CLOSURE) {
-                if (this.getMin() < 0 && this.getMax() < 0) {
-                    ret = this.child.toString(options)+"*";
-                } else if (this.getMin() == this.getMax()) {
-                    ret = this.child.toString(options)+"{"+this.getMin()+"}";
-                } else if (this.getMin() >= 0 && this.getMax() >= 0) {
-                    ret = this.child.toString(options)+"{"+this.getMin()+","+this.getMax()+"}";
-                } else if (this.getMin() >= 0 && this.getMax() < 0) {
-                    ret = this.child.toString(options)+"{"+this.getMin()+",}";
-                } else
-                    throw new RuntimeException("Token#toString(): CLOSURE "
-                                               +this.getMin()+", "+this.getMax());
-            } else {
-                if (this.getMin() < 0 && this.getMax() < 0) {
-                    ret = this.child.toString(options)+"*?";
-                } else if (this.getMin() == this.getMax()) {
-                    ret = this.child.toString(options)+"{"+this.getMin()+"}?";
-                } else if (this.getMin() >= 0 && this.getMax() >= 0) {
-                    ret = this.child.toString(options)+"{"+this.getMin()+","+this.getMax()+"}?";
-                } else if (this.getMin() >= 0 && this.getMax() < 0) {
-                    ret = this.child.toString(options)+"{"+this.getMin()+",}?";
-                } else
-                    throw new RuntimeException("Token#toString(): NONGREEDYCLOSURE "
-                                               +this.getMin()+", "+this.getMax());
-            }
-            return ret;
-        }
-    }
-
-    /**
-     * This class represents a node in parse tree.
-     */
-    static class ParenToken extends Token implements java.io.Serializable {
-        Token child;
-        int parennumber;
-
-        ParenToken(int type, Token tok, int paren) {
-            super(type);
-            this.child = tok;
-            this.parennumber = paren;
-        }
-
-        int size() {
-            return 1;
-        }
-        Token getChild(int index) {
-            return this.child;
-        }
-
-        int getParenNumber() {
-            return this.parennumber;
-        }
-
-        public String toString(int options) {
-            String ret = null;
-            switch (this.type) {
-              case PAREN:
-                if (this.parennumber == 0) {
-                    ret = "(?:"+this.child.toString(options)+")";
-                } else {
-                    ret = "("+this.child.toString(options)+")";
-                }
-                break;
-
-              case LOOKAHEAD:
-                ret = "(?="+this.child.toString(options)+")";
-                break;
-              case NEGATIVELOOKAHEAD:
-                ret = "(?!"+this.child.toString(options)+")";
-                break;
-              case LOOKBEHIND:
-                ret = "(?<="+this.child.toString(options)+")";
-                break;
-              case NEGATIVELOOKBEHIND:
-                ret = "(?<!"+this.child.toString(options)+")";
-                break;
-              case INDEPENDENT:
-                ret = "(?>"+this.child.toString(options)+")";
-                break;
-            }
-            return ret;
-        }
-    }
-
-    /**
-     * (?(condition)yes-pattern|no-pattern)
-     */
-    static class ConditionToken extends Token implements java.io.Serializable {
-        int refNumber;
-        Token condition;
-        Token yes;
-        Token no;
-        ConditionToken(int refno, Token cond, Token yespat, Token nopat) {
-            super(Token.CONDITION);
-            this.refNumber = refno;
-            this.condition = cond;
-            this.yes = yespat;
-            this.no = nopat;
-        }
-        int size() {
-            return this.no == null ? 1 : 2;
-        }
-        Token getChild(int index) {
-            if (index == 0)  return this.yes;
-            if (index == 1)  return this.no;
-            throw new RuntimeException("Internal Error: "+index);
-        }
-
-        public String toString(int options) {
-            String ret;
-            if (refNumber > 0) {
-                ret = "(?("+refNumber+")";
-            } else if (this.condition.type == Token.ANCHOR) {
-                ret = "(?("+this.condition+")";
-            } else {
-                ret = "(?"+this.condition;
-            }
-
-            if (this.no == null) {
-                ret += this.yes+")";
-            } else {
-                ret += this.yes+"|"+this.no+")";
-            }
-            return ret;
-        }
-    }
-
-    /**
-     * (ims-ims: .... )
-     */
-    static class ModifierToken extends Token implements java.io.Serializable {
-        Token child;
-        int add;
-        int mask;
-
-        ModifierToken(Token tok, int add, int mask) {
-            super(Token.MODIFIERGROUP);
-            this.child = tok;
-            this.add = add;
-            this.mask = mask;
-        }
-
-        int size() {
-            return 1;
-        }
-        Token getChild(int index) {
-            return this.child;
-        }
-
-        int getOptions() {
-            return this.add;
-        }
-        int getOptionsMask() {
-            return this.mask;
-        }
-
-        public String toString(int options) {
-            return "(?"
-                +(this.add == 0 ? "" : REUtil.createOptionString(this.add))
-                +(this.mask == 0 ? "" : REUtil.createOptionString(this.mask))
-                +":"
-                +this.child.toString(options)
-                +")";
-        }
-    }
-
-    /**
-     * This class represents a node in parse tree.
-     * for UNION or CONCAT.
-     */
-    static class UnionToken extends Token implements java.io.Serializable {
-        Vector children;
-
-        UnionToken(int type) {
-            super(type);
-        }
-
-        void addChild(Token tok) {
-            if (tok == null)  return;
-            if (this.children == null)  this.children = new Vector();
-            if (this.type == UNION) {
-                this.children.addElement(tok);
-                return;
-            }
-                                                // This is CONCAT, and new child is CONCAT.
-            if (tok.type == CONCAT) {
-                for (int i = 0;  i < tok.size();  i ++)
-                    this.addChild(tok.getChild(i)); // Recursion
-                return;
-            }
-            int size = this.children.size();
-            if (size == 0) {
-                this.children.addElement(tok);
-                return;
-            }
-            Token previous = (Token)this.children.elementAt(size-1);
-            if (!((previous.type == CHAR || previous.type == STRING)
-                  && (tok.type == CHAR || tok.type == STRING))) {
-                this.children.addElement(tok);
-                return;
-            }
-            
-            //System.err.println("Merge '"+previous+"' and '"+tok+"'.");
-
-            StringBuffer buffer;
-            int nextMaxLength = (tok.type == CHAR ? 2 : tok.getString().length());
-            if (previous.type == CHAR) {        // Replace previous token by STRING
-                buffer = new StringBuffer(2 + nextMaxLength);
-                int ch = previous.getChar();
-                if (ch >= 0x10000)
-                    buffer.append(REUtil.decomposeToSurrogates(ch));
-                else
-                    buffer.append((char)ch);
-                previous = Token.createString(null);
-                this.children.setElementAt(previous, size-1);
-            } else {                            // STRING
-                buffer = new StringBuffer(previous.getString().length() + nextMaxLength);
-                buffer.append(previous.getString());
-            }
-
-            if (tok.type == CHAR) {
-                int ch = tok.getChar();
-                if (ch >= 0x10000)
-                    buffer.append(REUtil.decomposeToSurrogates(ch));
-                else
-                    buffer.append((char)ch);
-            } else {
-                buffer.append(tok.getString());
-            }
-
-            ((StringToken)previous).string = new String(buffer);
-        }
-
-        int size() {
-            return this.children == null ? 0 : this.children.size();
-        }
-        Token getChild(int index) {
-            return (Token)this.children.elementAt(index);
-        }
-
-        public String toString(int options) {
-            String ret;
-            if (this.type == CONCAT) {
-                if (this.children.size() == 2) {
-                    Token ch = this.getChild(0);
-                    Token ch2 = this.getChild(1);
-                    if (ch2.type == CLOSURE && ch2.getChild(0) == ch) {
-                        ret = ch.toString(options)+"+";
-                    } else if (ch2.type == NONGREEDYCLOSURE && ch2.getChild(0) == ch) {
-                        ret = ch.toString(options)+"+?";
-                    } else
-                        ret = ch.toString(options)+ch2.toString(options);
-                } else {
-                    StringBuffer sb = new StringBuffer();
-                    for (int i = 0;  i < this.children.size();  i ++) {
-                        sb.append(((Token)this.children.elementAt(i)).toString(options));
-                    }
-                    ret = new String(sb);
-                }
-                return ret;
-            }
-            if (this.children.size() == 2 && this.getChild(1).type == EMPTY) {
-                ret = this.getChild(0).toString(options)+"?";
-            } else if (this.children.size() == 2
-                       && this.getChild(0).type == EMPTY) {
-                ret = this.getChild(1).toString(options)+"??";
-            } else {
-                StringBuffer sb = new StringBuffer();
-                sb.append(((Token)this.children.elementAt(0)).toString(options));
-                for (int i = 1;  i < this.children.size();  i ++) {
-                    sb.append((char)'|');
-                    sb.append(((Token)this.children.elementAt(i)).toString(options));
-                }
-                ret = new String(sb);
-            }
-            return ret;
-        }
-    }
-}
diff --git a/src/org/apache/xerces/utils/regex/message.properties b/src/org/apache/xerces/utils/regex/message.properties
deleted file mode 100644
index abe4880..0000000
--- a/src/org/apache/xerces/utils/regex/message.properties
+++ /dev/null
@@ -1,32 +0,0 @@
-parser.parse.1=Wrong character.
-parser.parse.2=Invalid reference number.
-parser.next.1=A character is required after \\.
-parser.next.2='?' is not expected.  '(?:' or '(?=' or '(?!' or '(?<' or '(?#' or '(?>'?
-parser.next.3='(?<=' or '(?<!' is expected.
-parser.next.4=A comment is not terminated.
-parser.factor.1=')' is expected.
-parser.factor.2=Unexpected end of the pattern in a modifier group.
-parser.factor.3=':' is expected.
-parser.factor.4=Unexpected end of the pattern in a conditional group.
-parser.factor.5=A back reference or an anchor or a lookahead or a lookbehind is expected in a conditional pattern.
-parser.factor.6=There are more than three choises in a conditional group.
-parser.atom.1=A character in U+0040-U+005f must follow \\c.
-parser.atom.2=A Category character or '{' is required.
-parser.atom.3=A property name is not closed by '}'.
-parser.atom.4=Unexpected meta character.
-parser.atom.5=Unknown property.
-parser.cc.1=A POSIX character class must be closed by ':]'.
-parser.cc.2=Unexpected end of the pattern in a character class.
-parser.cc.3=Unknown name for a POSIX character class.
-parser.cc.4='-' is invalid here.
-parser.cc.5=']' is expected.
-parser.cc.6='[' is invalid in a characer class.  Write '\\['.
-parser.cc.7=']' is invalid in a characer class.  Write '\\]'.
-parser.ope.1='[' is expected.
-parser.ope.2=')' or '-[' or '+[' or '&[' is expected.
-parser.descape.1=Invalid Unicode hex notation.
-parser.descape.2=Overflow in a hex notation.
-parser.descape.3='\\x{' must be closed by '}'.
-parser.descape.4=Invalid Unicode code point.
-parser.descape.5=An anchor must not be here.
-parser.process.1=This expression is not supported in the current option setting.
diff --git a/src/org/apache/xerces/utils/regex/message_ja.properties b/src/org/apache/xerces/utils/regex/message_ja.properties
deleted file mode 100644
index 9be8394..0000000
--- a/src/org/apache/xerces/utils/regex/message_ja.properties
+++ /dev/null
@@ -1,32 +0,0 @@
-parser.parse.1=\u3078\u3093\u306a\u6587\u5b57.
-parser.parse.2=\u5b58\u5728\u3057\u306a\u3044\u30b0\u30eb\u30fc\u30d7\u756a\u53f7\u3067\u3059.
-parser.next.1=\\ \u306e\u5f8c\u306b1\u6587\u5b57\u5fc5\u8981\u3067\u3059.
-parser.next.2='?' \u3092\u3053\u3053\u306b\u66f8\u304f\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093. \u3082\u3057\u304b\u3057\u3066 '(?:' \u304b '(?=' \u304b '(?!' \u304b '(?<' \u304b '(?#' \u304b '(?>' \u3067\u3059\u304b?
-parser.next.3='(?<=' \u304b '(?<!' \u304c\u5fc5\u8981\u3067\u3059.
-parser.next.4=\u8a3b\u91c8\u304c\u9589\u3058\u3066\u3044\u307e\u305b\u3093.
-parser.factor.1=')' \u304c\u5fc5\u8981\u3067\u3059.
-parser.factor.2=\u30aa\u30d7\u30b7\u30e7\u30f3\u4ed8\u304d\u30b0\u30eb\u30fc\u30d7\u306e\u4e2d\u3067\u30d1\u30bf\u30fc\u30f3\u304c\u7d42\u4e86\u3057\u3066\u3044\u307e\u3059.
-parser.factor.3=':' \u304c\u5fc5\u8981\u3067\u3059.
-parser.factor.4=\u6761\u4ef6\u4ed8\u304d\u30b0\u30eb\u30fc\u30d7\u306e\u4e2d\u3067\u30d1\u30bf\u30fc\u30f3\u304c\u7d42\u4e86\u3057\u3066\u3044\u307e\u3059.
-parser.factor.5=\u6761\u4ef6\u30d1\u30bf\u30fc\u30f3\u306b\u306f\u3001\u5f8c\u65b9\u53c2\u7167\u30fb\u30a2\u30f3\u30ab\u30fc\u30fb\u5148\u8aad\u307f\u30fb\u5f8c\u8aad\u307f\u306e\u307f\u4f7f\u7528\u3067\u304d\u307e\u3059.
-parser.factor.6=\u6761\u4ef6\u4ed8\u304d\u30b0\u30eb\u30fc\u30d7\u306e\u4e2d\u306b3\u500b\u4ee5\u4e0a\u306e\u9078\u629e\u3092\u66f8\u304f\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093.
-parser.atom.1=\\c \u306e\u5f8c\u306b\u306f\u30b3\u30fc\u30c9\u30dd\u30a4\u30f3\u30c8\u304c U+0040\uff5eU+005f \u306e\u7bc4\u56f2\u306e\u6587\u5b57\u304c\u5fc5\u8981\u3067\u3059.
-parser.atom.2=1\u6587\u5b57\u306e\u30ab\u30c6\u30b4\u30ea\u6587\u5b57\u304b '{' \u304c\u5fc5\u8981\u3067\u3059.
-parser.atom.3=\u30d7\u30ed\u30d1\u30c6\u30a3\u540d\u304c '}' \u3067\u9589\u3058\u3066\u3044\u307e\u305b\u3093.
-parser.atom.4=\u30e1\u30bf\u6587\u5b57\u304c\u5909\u306a\u3068\u3053\u308d\u306b\u3042\u308a\u307e\u3059.
-parser.atom.5=\u672a\u77e5\u306e\u30d7\u30ed\u30d1\u30c6\u30a3\u540d\u3067\u3059.
-parser.cc.1=POSIX \u6587\u5b57\u30af\u30e9\u30b9\u306f ':]' \u3067\u9589\u3058\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059.
-parser.cc.2=\u6587\u5b57\u30af\u30e9\u30b9\u5185\u3067\u30d1\u30bf\u30fc\u30f3\u304c\u7d42\u4e86\u3057\u3066\u3044\u307e\u3059.
-parser.cc.3=\u672a\u77e5\u306e POSIX \u6587\u5b57\u30af\u30e9\u30b9\u540d\u3067\u3059.
-parser.cc.4=\u3053\u3053\u306b '-' \u3092\u66f8\u304f\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093.
-parser.cc.5=']' \u304c\u5fc5\u8981\u3067\u3059.
-parser.cc.6=\u6587\u5b57\u30af\u30e9\u30b9\u5185\u3067\u306f '[' \u3092\u76f4\u63a5\u66f8\u304f\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093. '\\[' \u3068\u66f8\u3044\u3066\u304f\u3060\u3055\u3044.
-parser.cc.7=\u6587\u5b57\u30af\u30e9\u30b9\u5185\u3067\u306f ']' \u3092\u76f4\u63a5\u66f8\u304f\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093. '\\]' \u3068\u66f8\u3044\u3066\u304f\u3060\u3055\u3044.
-parser.ope.1='[' \u304c\u5fc5\u8981\u3067\u3059.
-parser.ope.2=')' \u304b '-[' \u304b '+[' \u304b '&[' \u304c\u5fc5\u8981\u3067\u3059.
-parser.descape.1=\u30b3\u30fc\u30c9\u30dd\u30a4\u30f3\u30c8\u306e16\u9032\u6570\u8868\u8a18\u4e2d\u306b\u9593\u9055\u3063\u305f\u6587\u5b57\u304c\u3042\u308a\u307e\u3059.
-parser.descape.2=\u30b3\u30fc\u30c9\u30dd\u30a4\u30f3\u30c8\u306e\u6570\u5024\u304c\u5927\u304d\u3059\u304e\u307e\u3059.
-parser.descape.3='\\x{' \u306f '}' \u3067\u9589\u3058\u306a\u3051\u308c\u3070\u3044\u3051\u307e\u305b\u3093.
-parser.descape.4=Unicode \u306e\u30b3\u30fc\u30c9\u30dd\u30a4\u30f3\u30c8\u3068\u3057\u3066\u4e0d\u6b63\u3067\u3059.
-parser.descape.5=\u30a2\u30f3\u30ab\u30fc\u3092\u3053\u3053\u306b\u66f8\u304f\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093.
-parser.process.1=\u3053\u306e\u8868\u73fe\u306f\u73fe\u5728\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u8a2d\u5b9a\u3067\u306f\u4f7f\u7528\u3067\u304d\u307e\u305b\u3093.
diff --git a/src/org/apache/xerces/validators/Makefile b/src/org/apache/xerces/validators/Makefile
deleted file mode 100644
index a71315d..0000000
--- a/src/org/apache/xerces/validators/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Makefile for directory ./org/apache/xerces/validators
-
-TARGETS=
-
-DIRS = datatype dtd schema common
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xerces/validators/common/CMAny.java b/src/org/apache/xerces/validators/common/CMAny.java
deleted file mode 100644
index 4e35b68..0000000
--- a/src/org/apache/xerces/validators/common/CMAny.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.framework.XMLContentSpec;
-import org.apache.xerces.utils.ImplementationMessages;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringPool;
-
-/**
- * Content model any node.
- *
- * @version $Id$
- */
-public class CMAny
-    extends CMNode {
-
-    //
-    // Data
-    //
-
-    /** 
-     * The any content model type. This value is one of the following:
-     * XMLContentSpec.CONTENTSPECNODE_ANY, 
-     * XMLContentSpec.CONTENTSPECNODE_ANY_OTHER,
-     * XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL.
-     */
-    private int fType;
-
-    /**
-     * URI of the any content model. This value is set if the type is
-     * of the following:
-     * XMLContentSpec.CONTENTSPECNODE_ANY, 
-     * XMLContentSpec.CONTENTSPECNODE_ANY_OTHER.
-     */
-    private int fURI;
-
-    /**
-     * Part of the algorithm to convert a regex directly to a DFA
-     * numbers each leaf sequentially. If its -1, that means its an
-     * epsilon node. Zero and greater are non-epsilon positions.
-     */
-    private int fPosition = -1;
-
-    //
-    // Constructors
-    //
-
-    /** Constructs a content model any. */
-    public CMAny(int type, int uri, int position) throws CMException {
-        super(type);
-
-        // Store the information
-        fType = type;
-        fURI = uri;
-        fPosition = position;
-    }
-
-    //
-    // Package methods
-    //
-
-    final int getType() {
-        return fType;
-    }
-
-    final int getURI() {
-        return fURI;
-    }
-
-    final int getPosition()
-    {
-        return fPosition;
-    }
-
-    final void setPosition(int newPosition)
-    {
-        fPosition = newPosition;
-    }
-
-    //
-    // CMNode methods
-    //
-
-    // package
-
-    boolean isNullable() throws CMException
-    {
-        // Leaf nodes are never nullable unless its an epsilon node
-        return (fPosition == -1);
-    }
-
-    String toString(StringPool stringPool)
-    {
-        StringBuffer strRet = new StringBuffer();
-        strRet.append("(");
-        strRet.append("##any:uri=");
-        strRet.append(stringPool.toString(fURI));
-        strRet.append(')');
-        if (fPosition >= 0)
-        {
-            strRet.append
-            (
-                " (Pos:"
-                + new Integer(fPosition).toString()
-                + ")"
-            );
-        }
-        return strRet.toString();
-    }
-
-    // protected
-
-    protected void calcFirstPos(CMStateSet toSet) throws CMException
-    {
-        // If we are an epsilon node, then the first pos is an empty set
-        if (fPosition == -1)
-            toSet.zeroBits();
-
-        // Otherwise, its just the one bit of our position
-        else
-            toSet.setBit(fPosition);
-    }
-
-    protected void calcLastPos(CMStateSet toSet) throws CMException
-    {
-        // If we are an epsilon node, then the last pos is an empty set
-        if (fPosition == -1)
-            toSet.zeroBits();
-
-        // Otherwise, its just the one bit of our position
-        else
-            toSet.setBit(fPosition);
-    }
-
-} // class CMAny
diff --git a/src/org/apache/xerces/validators/common/CMBinOp.java b/src/org/apache/xerces/validators/common/CMBinOp.java
deleted file mode 100644
index 548c837..0000000
--- a/src/org/apache/xerces/validators/common/CMBinOp.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.framework.XMLContentSpec;
-import org.apache.xerces.utils.ImplementationMessages;
-
-/**
- *
- * @version
- */
-public class CMBinOp extends CMNode
-{
-    // -------------------------------------------------------------------
-    //  Constructors
-    // -------------------------------------------------------------------
-    public CMBinOp(int type, CMNode leftNode, CMNode rightNode) throws CMException
-    {
-        super(type);
-
-        // Insure that its one of the types we require
-        if ((type() != XMLContentSpec.CONTENTSPECNODE_CHOICE)
-        &&  (type() != XMLContentSpec.CONTENTSPECNODE_SEQ))
-        {
-            throw new CMException(ImplementationMessages.VAL_BST);
-        }
-
-        // Store the nodes and init any data that needs it
-        fLeftChild = leftNode;
-        fRightChild = rightNode;
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Package, final methods
-    // -------------------------------------------------------------------
-    final CMNode getLeft()
-    {
-        return fLeftChild;
-    }
-
-    final CMNode getRight()
-    {
-        return fRightChild;
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Package, inherited methods
-    // -------------------------------------------------------------------
-    boolean isNullable() throws CMException
-    {
-        //
-        //  If its an alternation, then if either child is nullable then
-        //  this node is nullable. If its a concatenation, then both of
-        //  them have to be nullable.
-        //
-        if (type() == XMLContentSpec.CONTENTSPECNODE_CHOICE)
-            return (fLeftChild.isNullable() || fRightChild.isNullable());
-        else if (type() == XMLContentSpec.CONTENTSPECNODE_SEQ)
-            return (fLeftChild.isNullable() && fRightChild.isNullable());
-        else
-            throw new CMException(ImplementationMessages.VAL_BST);
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Protected, inherited methods
-    // -------------------------------------------------------------------
-    protected void calcFirstPos(CMStateSet toSet) throws CMException
-    {
-        if (type() == XMLContentSpec.CONTENTSPECNODE_CHOICE)
-        {
-            // Its the the union of the first positions of our children.
-            toSet.setTo(fLeftChild.firstPos());
-            toSet.union(fRightChild.firstPos());
-        }
-         else if (type() == XMLContentSpec.CONTENTSPECNODE_SEQ)
-        {
-            //
-            //  If our left child is nullable, then its the union of our
-            //  children's first positions. Else is our left child's first
-            //  positions.
-            //
-            toSet.setTo(fLeftChild.firstPos());
-            if (fLeftChild.isNullable())
-                toSet.union(fRightChild.firstPos());
-        }
-         else
-        {
-            throw new CMException(ImplementationMessages.VAL_BST);
-        }
-    }
-
-    protected void calcLastPos(CMStateSet toSet) throws CMException
-    {
-        if (type() == XMLContentSpec.CONTENTSPECNODE_CHOICE)
-        {
-            // Its the the union of the first positions of our children.
-            toSet.setTo(fLeftChild.lastPos());
-            toSet.union(fRightChild.lastPos());
-        }
-         else if (type() == XMLContentSpec.CONTENTSPECNODE_SEQ)
-        {
-            //
-            //  If our right child is nullable, then its the union of our
-            //  children's last positions. Else is our right child's last
-            //  positions.
-            //
-            toSet.setTo(fRightChild.lastPos());
-            if (fRightChild.isNullable())
-                toSet.union(fLeftChild.lastPos());
-        }
-         else
-        {
-            throw new CMException(ImplementationMessages.VAL_BST);
-        }
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Private data members
-    //
-    //  fLeftChild
-    //  fRightChild
-    //      These are the references to the two nodes that are on either
-    //      side of this binary operation.
-    // -------------------------------------------------------------------
-    private CMNode  fLeftChild;
-    private CMNode  fRightChild;
-};
diff --git a/src/org/apache/xerces/validators/common/CMException.java b/src/org/apache/xerces/validators/common/CMException.java
deleted file mode 100644
index 47d11d2..0000000
--- a/src/org/apache/xerces/validators/common/CMException.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-/**
- * CMException is thrown during CMNode operations
- *
- * @version
- */
-public class CMException extends Exception
-{
-    // -------------------------------------------------------------------
-    //  Constructors
-    // -------------------------------------------------------------------
-    public CMException(int errCode)
-    {
-        fErrorCode = errCode;
-    }
-
-    // -------------------------------------------------------------------
-    //  Package methods
-    // -------------------------------------------------------------------
-    public int getErrorCode()
-    {
-        return fErrorCode;
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Private constants
-    // -------------------------------------------------------------------
-    static final int       fUnused = -1000;
-
-
-    // -------------------------------------------------------------------
-    //  Private data members
-    //
-    //  fErrorCode
-    //      The id from ErrorCode for the error being reported.
-    // -------------------------------------------------------------------
-    private int     fErrorCode;
-};
diff --git a/src/org/apache/xerces/validators/common/CMLeaf.java b/src/org/apache/xerces/validators/common/CMLeaf.java
deleted file mode 100644
index add5b82..0000000
--- a/src/org/apache/xerces/validators/common/CMLeaf.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.framework.XMLContentSpec;
-import org.apache.xerces.utils.ImplementationMessages;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringPool;
-
-/**
- * Content model leaf node.
- *
- * @version $Id$
- */
-public class CMLeaf 
-    extends CMNode {
-
-    //
-    // Data
-    //
-
-    /** This is the element that this leaf represents. */
-    private QName fElement = new QName();
-
-    /**
-     * Part of the algorithm to convert a regex directly to a DFA
-     * numbers each leaf sequentially. If its -1, that means its an
-     * epsilon node. Zero and greater are non-epsilon positions.
-     */
-    private int fPosition = -1;
-
-    //
-    // Constructors
-    //
-
-    /** Constructs a content model leaf. */
-    public CMLeaf(QName element, int position) throws CMException {
-        super(XMLContentSpec.CONTENTSPECNODE_LEAF);
-
-        // Store the element index and position
-        fElement.setValues(element);
-        fPosition = position;
-    }
-
-    /** Constructs a content model leaf. */
-    public CMLeaf(QName element) throws CMException {
-        super(XMLContentSpec.CONTENTSPECNODE_LEAF);
-
-        // Store the element index and position
-        fElement.setValues(element);
-    }
-
-    //
-    // Package methods
-    //
-
-    final QName getElement()
-    {
-        return fElement;
-    }
-
-    final int getPosition()
-    {
-        return fPosition;
-    }
-
-    final void setPosition(int newPosition)
-    {
-        fPosition = newPosition;
-    }
-
-    //
-    // CMNode methods
-    //
-
-    // package
-
-    boolean isNullable() throws CMException
-    {
-        // Leaf nodes are never nullable unless its an epsilon node
-        return (fPosition == -1);
-    }
-
-    String toString(StringPool stringPool)
-    {
-        StringBuffer strRet = new StringBuffer(fElement.toString());
-        strRet.append(" (");
-        strRet.append(stringPool.toString(fElement.uri));
-        strRet.append(',');
-        strRet.append(stringPool.toString(fElement.localpart));
-        strRet.append(')');
-        if (fPosition >= 0)
-        {
-            strRet.append
-            (
-                " (Pos:"
-                + new Integer(fPosition).toString()
-                + ")"
-            );
-        }
-        return strRet.toString();
-    }
-
-    // protected
-
-    protected void calcFirstPos(CMStateSet toSet) throws CMException
-    {
-        // If we are an epsilon node, then the first pos is an empty set
-        if (fPosition == -1)
-            toSet.zeroBits();
-
-        // Otherwise, its just the one bit of our position
-        else
-            toSet.setBit(fPosition);
-    }
-
-    protected void calcLastPos(CMStateSet toSet) throws CMException
-    {
-        // If we are an epsilon node, then the last pos is an empty set
-        if (fPosition == -1)
-            toSet.zeroBits();
-
-        // Otherwise, its just the one bit of our position
-        else
-            toSet.setBit(fPosition);
-    }
-
-} // class CMLeaf
diff --git a/src/org/apache/xerces/validators/common/CMNode.java b/src/org/apache/xerces/validators/common/CMNode.java
deleted file mode 100644
index 6f45eec..0000000
--- a/src/org/apache/xerces/validators/common/CMNode.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-/**
- *
- * @version
- */
-public abstract class CMNode
-{
-    // -------------------------------------------------------------------
-    //  Constructors
-    // -------------------------------------------------------------------
-    CMNode(int type) throws CMException
-    {
-        fType = type;
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Package, abstract methods
-    // -------------------------------------------------------------------
-    abstract boolean isNullable() throws CMException;
-
-
-    // -------------------------------------------------------------------
-    //  Package final methods
-    // -------------------------------------------------------------------
-    final int type()
-    {
-        return fType;
-    }
-
-    final CMStateSet firstPos() throws CMException
-    {
-        if (fFirstPos == null)
-        {
-            fFirstPos = new CMStateSet(fMaxStates);
-            calcFirstPos(fFirstPos);
-        }
-        return fFirstPos;
-    }
-
-    final CMStateSet lastPos() throws CMException
-    {
-        if (fLastPos == null)
-        {
-            fLastPos = new CMStateSet(fMaxStates);
-            calcLastPos(fLastPos);
-        }
-        return fLastPos;
-    }
-
-    final void setFollowPos(CMStateSet setToAdopt)
-    {
-        fFollowPos = setToAdopt;
-    }
-
-    final void setMaxStates(int maxStates)
-    {
-        fMaxStates = maxStates;
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Protected, abstract methods
-    // -------------------------------------------------------------------
-    protected abstract void calcFirstPos(CMStateSet toSet) throws CMException;
-
-    protected abstract void calcLastPos(CMStateSet toSet) throws CMException;
-
-
-    // -------------------------------------------------------------------
-    //  Private data members
-    //
-    //  fType
-    //      The type of node. This indicates whether its a leaf or an
-    //      operation. Though we also do derived classes for these types,
-    //      it is too expensive to use runtime typing to find this out.
-    //      This is one of the ContentSpecNode.NODE_XXX types.
-    //
-    //  fFirstPos
-    //      The set of NFA states that represent the entry states of this
-    //      node in the DFA.
-    //
-    //  fFollowPos
-    //      The set of NFA states that can be gotten to from from this
-    //      node in the DFA.
-    //
-    //  fLastPos
-    //      The set of NFA states that represent the final states of this
-    //      node in the DFA.
-    //
-    //  fMaxStates
-    //      The maximum number of states that the NFA has, which means the
-    //      max number of NFA states that have to be traced in the state
-    //      sets during the building of the DFA. Its unfortunate that it
-    //      has to be stored redundantly, but we need to fault in the
-    //      state set members and they have to be sized to this size. We
-    //      init to to -1 so it will cause an error if its used without
-    //      being initialized.
-    // -------------------------------------------------------------------
-    private int         fType;
-    private CMStateSet  fFirstPos   = null;
-    private CMStateSet  fFollowPos  = null;
-    private CMStateSet  fLastPos    = null;
-    private int         fMaxStates  = -1;
-};
diff --git a/src/org/apache/xerces/validators/common/CMStateSet.java b/src/org/apache/xerces/validators/common/CMStateSet.java
deleted file mode 100644
index 3ec278c..0000000
--- a/src/org/apache/xerces/validators/common/CMStateSet.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.utils.ImplementationMessages;
-
-/**
- * This class is a very simple bitset class. The DFA content model code needs
- * to support a bit set, but the java BitSet class is way, way overkill. Our
- * bitset never needs to be expanded after creation, hash itself, etc...
- *
- * Since the vast majority of content models will never require more than 64
- * bits, and since allocation of anything in Java is expensive, this class
- * provides a hybrid implementation that uses two ints for instances that use
- * 64 bits or fewer. It has a byte array reference member which will only be
- * used if more than 64 bits are required.
- *
- * Note that the code that uses this class will never perform operations
- * on sets of different sizes, so that check does not have to be made here.
- *
- * @version
- */
-class CMStateSet
-{
-    // -------------------------------------------------------------------
-    //  Constructors
-    // -------------------------------------------------------------------
-    CMStateSet(int bitCount) throws CMException
-    {
-        // Store the required bit count and insure its legal
-        fBitCount = bitCount;
-        if (fBitCount < 0)
-            throw new CMException(ImplementationMessages.VAL_CMSI);
-
-        //
-        //  See if we need to allocate the byte array or whether we can live
-        //  within the 64 bit high performance scheme.
-        //
-        if (fBitCount > 64)
-        {
-            fByteCount = fBitCount / 8;
-            if (fBitCount % 8 != 0)
-                fByteCount++;
-            fByteArray = new byte[fByteCount];
-        }
-
-        // Init all the bits to zero
-        zeroBits();
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Public inherited methods
-    // -------------------------------------------------------------------
-    public String toString()
-    {
-        StringBuffer strRet = new StringBuffer();
-        try
-        {
-            strRet.append("{");
-            for (int index = 0; index < fBitCount; index++)
-            {
-                if (getBit(index))
-                    strRet.append(" " + index);
-            }
-            strRet.append(" }");
-        }
-
-        catch(CMException exToCatch)
-        {
-            //
-            //  We know this won't happen but we have to catch it to avoid it
-            //  having to be in our 'throws' list.
-            //
-        }
-        return strRet.toString();
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Package final methods
-    // -------------------------------------------------------------------
-    final void intersection(CMStateSet setToAnd)
-    {
-        if (fBitCount < 65)
-        {
-            fBits1 &= setToAnd.fBits1;
-            fBits2 &= setToAnd.fBits2;
-        }
-         else
-        {
-            for (int index = fByteCount - 1; index >= 0; index--)
-                fByteArray[index] &= setToAnd.fByteArray[index];
-        }
-    }
-
-    final boolean getBit(int bitToGet) throws CMException
-    {
-        if (bitToGet >= fBitCount)
-            throw new CMException(ImplementationMessages.VAL_CMSI);
-
-        if (fBitCount < 65)
-        {
-            final int mask = (0x1 << (bitToGet % 32));
-            if (bitToGet < 32)
-                return (fBits1 & mask) != 0;
-            else
-                return (fBits2 & mask) != 0;
-        }
-         else
-        {
-            // Create the mask and byte values
-            final byte mask = (byte)(0x1 << (bitToGet % 8));
-            final int ofs = bitToGet >> 3;
-
-            // And access the right bit and byte
-            return ((fByteArray[ofs] & mask) != 0);
-        }
-    }
-
-    final boolean isEmpty()
-    {
-        if (fBitCount < 65)
-        {
-            return ((fBits1 == 0) && (fBits2 == 0));
-        }
-         else
-        {
-            for (int index = fByteCount - 1; index >= 0; index--)
-            {
-                if (fByteArray[index] != 0)
-                    return false;
-            }
-        }
-        return true;
-    }
-
-    final boolean isSameSet(CMStateSet setToCompare)
-    {
-        if (fBitCount != setToCompare.fBitCount)
-            return false;
-
-        if (fBitCount < 65)
-        {
-            return ((fBits1 == setToCompare.fBits1)
-            &&      (fBits2 == setToCompare.fBits2));
-        }
-
-        for (int index = fByteCount - 1; index >= 0; index--)
-        {
-            if (fByteArray[index] != setToCompare.fByteArray[index])
-                return false;
-        }
-        return true;
-    }
-
-    final void union(CMStateSet setToOr)
-    {
-        if (fBitCount < 65)
-        {
-            fBits1 |= setToOr.fBits1;
-            fBits2 |= setToOr.fBits2;
-        }
-         else
-        {
-            for (int index = fByteCount - 1; index >= 0; index--)
-                fByteArray[index] |= setToOr.fByteArray[index];
-        }
-    }
-
-    final void setBit(int bitToSet) throws CMException
-    {
-        if (bitToSet >= fBitCount)
-            throw new CMException(ImplementationMessages.VAL_CMSI);
-
-        if (fBitCount < 65)
-        {
-            final int mask = (0x1 << (bitToSet % 32));
-            if (bitToSet < 32)
-            {
-                fBits1 &= ~mask;
-                fBits1 |= mask;
-            }
-             else
-            {
-                fBits2 &= ~mask;
-                fBits2 |= mask;
-            }
-        }
-         else
-        {
-            // Create the mask and byte values
-            final byte mask = (byte)(0x1 << (bitToSet % 8));
-            final int ofs = bitToSet >> 3;
-
-            // And access the right bit and byte
-            fByteArray[ofs] &= ~mask;
-            fByteArray[ofs] |= mask;
-        }
-    }
-
-    final void setTo(CMStateSet srcSet) throws CMException
-    {
-        // They have to be the same size
-        if (fBitCount != srcSet.fBitCount)
-            throw new CMException(ImplementationMessages.VAL_CMSI);
-        
-        if (fBitCount < 65)
-        {
-            fBits1 = srcSet.fBits1;
-            fBits2 = srcSet.fBits2;
-        }
-         else
-        {
-            for (int index = fByteCount - 1; index >= 0; index--)
-                fByteArray[index] = srcSet.fByteArray[index];
-        }
-    }
-
-    final void zeroBits()
-    {
-        if (fBitCount < 65)
-        {
-            fBits1 = 0;
-            fBits2 = 0;
-        }
-         else
-        {
-            for (int index = fByteCount - 1; index >= 0; index--)
-                fByteArray[index] = 0;
-        }
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Private data members
-    //
-    //  fBitCount
-    //      The count of bits that the outside world wants to support,
-    //      so its the max bit index plus one.
-    //
-    //  fByteCount
-    //      If the bit count is > 64, then we use the fByteArray member to
-    //      store the bits, and this indicates its size in bytes. Otherwise
-    //      its value is meaningless.
-    //
-    //  fBits1
-    //  fBits2
-    //      When the bit count is < 64 (very common), these hold the bits.
-    //      Otherwise, the fByteArray member holds htem.
-    // -------------------------------------------------------------------
-    int         fBitCount;
-    int         fByteCount;
-    int         fBits1;
-    int         fBits2;
-    byte[]      fByteArray;
-};
diff --git a/src/org/apache/xerces/validators/common/CMUniOp.java b/src/org/apache/xerces/validators/common/CMUniOp.java
deleted file mode 100644
index d502ebb..0000000
--- a/src/org/apache/xerces/validators/common/CMUniOp.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.framework.XMLContentSpec;
-import org.apache.xerces.utils.ImplementationMessages;
-
-/**
- *
- * @version
- */
-public class CMUniOp extends CMNode
-{
-    // -------------------------------------------------------------------
-    //  Constructors
-    // -------------------------------------------------------------------
-    public CMUniOp(int type, CMNode childNode) throws CMException
-    {
-        super(type);
-
-        // Insure that its one of the types we require
-        if ((type() != XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE)
-        &&  (type() != XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
-        &&  (type() != XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE))
-        {
-            throw new CMException(ImplementationMessages.VAL_UST);
-        }
-
-        // Store the node and init any data that needs it
-        fChild = childNode;
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Package, final methods
-    // -------------------------------------------------------------------
-    final CMNode getChild()
-    {
-        return fChild;
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Package, inherited methods
-    // -------------------------------------------------------------------
-    boolean isNullable() throws CMException
-    {
-        //
-        //  For debugging purposes, make sure we got rid of all non '*'
-        //  repetitions. Otherwise, '*' style nodes are always nullable.
-        //
-        if ((type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE)
-        ||  (type() == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE))
-        {
-            throw new CMException(ImplementationMessages.VAL_UST);
-        }
-        return true;
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Protected, inherited methods
-    // -------------------------------------------------------------------
-    protected void calcFirstPos(CMStateSet toSet) throws CMException
-    {
-        // Its just based on our child node's first pos
-        toSet.setTo(fChild.firstPos());
-    }
-
-    protected void calcLastPos(CMStateSet toSet) throws CMException
-    {
-        // Its just based on our child node's last pos
-        toSet.setTo(fChild.lastPos());
-    }
-
-
-    // -------------------------------------------------------------------
-    //  Private data members
-    //
-    //  fChild
-    //      This is the reference to the one child that we have for this
-    //      unary operation.
-    // -------------------------------------------------------------------
-    private CMNode  fChild;
-};
diff --git a/src/org/apache/xerces/validators/common/ContentLeafNameTypeVector.java b/src/org/apache/xerces/validators/common/ContentLeafNameTypeVector.java
deleted file mode 100644
index f99a21f..0000000
--- a/src/org/apache/xerces/validators/common/ContentLeafNameTypeVector.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.utils.QName;
-
-/**
- * A light-weight class that stored the leaf names and types from a DFAContentModel
- * @version
- */
-
-public final class ContentLeafNameTypeVector {
-    //
-    // Data members
-    //
-
-    public QName[] leafNames = null;
-    public int[] leafTypes = null;
-    public int leafCount = 0;
-
-    //
-    // Constructors
-    //
-
-    public ContentLeafNameTypeVector () {
-    }
-    
-    public ContentLeafNameTypeVector (QName[] names, int[] types, int count) {
-        setValues(names, types, count);
-    }
-
-    public ContentLeafNameTypeVector (ContentLeafNameTypeVector clntv) {
-        this(clntv.leafNames, clntv.leafTypes, clntv.leafCount);
-    }
-
-    //
-    // setters
-    //
-    public void setValues(QName[] names, int[] types, int count) {
-        if (count > 0) {
-            leafNames = new QName[count];
-            leafTypes = new int[count];
-            leafCount = count;
-
-            System.arraycopy( names, 0, leafNames, 0, count);
-            System.arraycopy( types, 0, leafTypes, 0, count);
-        }
-    }
-
-}
diff --git a/src/org/apache/xerces/validators/common/DFAContentModel.java b/src/org/apache/xerces/validators/common/DFAContentModel.java
deleted file mode 100644
index 7273da9..0000000
--- a/src/org/apache/xerces/validators/common/DFAContentModel.java
+++ /dev/null
@@ -1,1269 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.framework.XMLContentSpec;
-import org.apache.xerces.utils.ImplementationMessages;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.validators.schema.EquivClassComparator;
-//import org.apache.xerces.utils.StringPool;
-
-/**
- * DFAContentModel is the derivative of ContentModel that does
- * all of the non-trivial element content validation. This class does 
- * the conversion from the regular expression to the DFA that 
- * it then uses in its validation algorithm.
- * <p>
- * <b>Note:</b> Upstream work insures that this class will never see
- * a content model with PCDATA in it. Any model with PCDATA is 'mixed' 
- * and is handled via the MixedContentModel class since mixed models 
- * are very constrained in form and easily handled via a special case. 
- * This also makes implementation of this class much easier.
- *
- * @version $Id$
- */
-public class DFAContentModel 
-    implements XMLContentModel {
-
-    //
-    // Constants
-    //
-    // special strings
-
-    /** Epsilon string. */
-    //private static final String fEpsilonString = "<<CMNODE_EPSILON>>";
-    private static final int EPSILON = -2;
-
-    /** End-of-content string. */
-    //private static final String fEOCString = "<<CMNODE_EOC>>";
-    private static final int EOC     = -3;
-
-    // debugging
-
-    /** Set to true to debug content model validation. */
-    private static final boolean DEBUG_VALIDATE_CONTENT = false;
-
-    //
-    // Data
-    //
-
-    /* this is the EquivClassComparator object */
-    private EquivClassComparator comparator = null;
-
-    /**
-     * This is the map of unique input symbol elements to indices into
-     * each state's per-input symbol transition table entry. This is part
-     * of the built DFA information that must be kept around to do the
-     * actual validation.
-     */
-    private QName fElemMap[] = null;
-
-    /**
-     * This is a map of whether the element map contains information 
-     * related to ANY models.
-     */
-    private int fElemMapType[] = null;
-
-    /** The element map size. */
-    private int fElemMapSize = 0;
-
-    /** Boolean to allow DTDs to validate even with namespace support. */
-    private boolean fDTD;
-
-    /**
-     * The string index for the 'end of content' string that we add to
-     * the string pool. This is used as the special name of an element
-     * that represents the end of the syntax tree.
-     */
-    private int fEOCIndex = 0;
-
-    /**
-     * The NFA position of the special EOC (end of content) node. This
-     * is saved away since it's used during the DFA build.
-     */
-    private int fEOCPos = 0;
-
-    /**
-     * The string index for the 'epsilon' string that we add to the
-     * string pool. This represents epsilon node transitions in the
-     * syntax tree.
-     */
-    private int fEpsilonIndex = 0;
-
-    /**
-     * This is an array of booleans, one per state (there are
-     * fTransTableSize states in the DFA) that indicates whether that
-     * state is a final state.
-     */
-    private boolean fFinalStateFlags[] = null;
-
-    /**
-     * The list of follow positions for each NFA position (i.e. for each
-     * non-epsilon leaf node.) This is only used during the building of
-     * the DFA, and is let go afterwards.
-     */
-    private CMStateSet fFollowList[] = null;
-
-    /**
-     * This is the head node of our intermediate representation. It is
-     * only non-null during the building of the DFA (just so that it
-     * does not have to be passed all around.) Once the DFA is built,
-     * this is no longer required so its nulled out.
-     */
-    private CMNode fHeadNode = null;
-
-    /**
-     * The count of leaf nodes. This is an important number that set some
-     * limits on the sizes of data structures in the DFA process.
-     */
-    private int fLeafCount = 0;
-
-    /**
-     * An array of non-epsilon leaf nodes, which is used during the DFA
-     * build operation, then dropped.
-     */
-    private CMLeaf fLeafList[] = null;
-
-    /** Array mapping ANY types to the leaf list. */
-    private int fLeafListType[] = null;
-
-    private ContentLeafNameTypeVector fLeafNameTypeVector = null;
-
-    /**
-     * The string pool of our parser session. This is set during construction
-     * and kept around.
-     */
-    //private StringPool fStringPool = null;
-
-    /**
-     * This is the transition table that is the main by product of all
-     * of the effort here. It is an array of arrays of ints. The first
-     * dimension is the number of states we end up with in the DFA. The
-     * second dimensions is the number of unique elements in the content
-     * model (fElemMapSize). Each entry in the second dimension indicates
-     * the new state given that input for the first dimension's start
-     * state.
-     * <p>
-     * The fElemMap array handles mapping from element indexes to
-     * positions in the second dimension of the transition table.
-     */
-    private int fTransTable[][] = null;
-
-    /**
-     * The number of valid entries in the transition table, and in the other
-     * related tables such as fFinalStateFlags.
-     */
-    private int fTransTableSize = 0;
-
-    /**
-     * Flag that indicates that even though we have a "complicated"
-     * content model, it is valid to have no content. In other words,
-     * all parts of the content model are optional. For example:
-     * <pre>
-     *      &lt;!ELEMENT AllOptional (Optional*,NotRequired?)&gt;
-     * </pre>
-     */
-    private boolean fEmptyContentIsValid = false;
-
-    // temp variables
-
-    /** Temporary qualified name. */
-    private QName fQName = new QName();
-
-    //
-    // Constructors
-    //
-
-    /**
-     * Constructs a DFA content model.
-     *
-     * @param stringPool    The string pool.
-     * @param syntaxTree    The syntax tree of the content model.
-     * @param leafCount     The number of leaves.
-     *
-     * @exception CMException Thrown if DMA can't be built.
-     */
-
-   // public DFAContentModel(StringPool stringPool, 
-   public DFAContentModel( CMNode syntaxTree, 
-                           int leafCount) throws CMException {
-       this(syntaxTree, leafCount, false);
-   }
-
-    /**
-     * Constructs a DFA content model.
-     *
-     * @param stringPool    The string pool.
-     * @param syntaxTree    The syntax tree of the content model.
-     * @param leafCount     The number of leaves.
-     *
-     * @exception CMException Thrown if DMA can't be built.
-     */
-
-   // public DFAContentModel(StringPool stringPool, 
-   public DFAContentModel( CMNode syntaxTree, 
-                           int leafCount, boolean dtd) throws CMException {
-
-        // Store away our index and pools in members
-        //fStringPool = stringPool;
-        fLeafCount = leafCount;
-
-        //
-        //  Create some string pool indexes that represent the names of some
-        //  magical nodes in the syntax tree.
-        //
-        /*** Defect 945 ***
-        if (fEpsilonString == null)
-        {
-            fEpsilonString = new String("<<CMNODE_EPSILON>>");
-            fEpsilonString.intern();
-            fEOCString = new String("<<CMNODE_EOC>>");
-            fEOCString.intern();
-        }
-        /***/
-
-       // fEpsilonIndex = fStringPool.addSymbol(fEpsilonString);
-       // fEOCIndex = fStringPool.addSymbol(fEOCString);
-
-        fEpsilonIndex = EPSILON;
-        fEOCIndex     = EOC;
-
-        fDTD = dtd;
-
-        //
-        //  Ok, so lets grind through the building of the DFA. This method
-        //  handles the high level logic of the algorithm, but it uses a
-        //  number of helper classes to do its thing.
-        //
-        //  In order to avoid having hundreds of references to the error and
-        //  string handlers around, this guy and all of his helper classes
-        //  just throw a simple exception and we then pass it along.
-        //
-        buildDFA(syntaxTree);
-    }
-
-    //
-    // XMLContentModel methods
-    //
-    
-    /**
-     * Check that the specified content is valid according to this
-     * content model. This method can also be called to do 'what if' 
-     * testing of content models just to see if they would be valid.
-     * <p>
-     * A value of -1 in the children array indicates a PCDATA node. All other 
-     * indexes will be positive and represent child elements. The count can be
-     * zero, since some elements have the EMPTY content model and that must be 
-     * confirmed.
-     *
-     * @param children The children of this element.  Each integer is an index within
-     *                 the <code>StringPool</code> of the child element name.  An index
-     *                 of -1 is used to indicate an occurrence of non-whitespace character
-     *                 data.
-     * @param offset Offset into the array where the children starts.
-     * @param length The number of entries in the <code>children</code> array.
-     *
-     * @return The value -1 if fully valid, else the 0 based index of the child
-     *         that first failed. If the value returned is equal to the number
-     *         of children, then the specified children are valid but additional
-     *         content is required to reach a valid ending state.
-     *
-     * @exception CMException Thrown on error.
-     */
-    public int validateContent(QName children[], int offset, int length) throws CMException {
-
-        if (DEBUG_VALIDATE_CONTENT) 
-            System.out.println("DFAContentModel#validateContent");
-
-        //
-        // A DFA content model must *always* have at least 1 child
-        // so a failure is given if no children present.
-        // 
-        // Defect 782: This is an incorrect statement because a DFA
-        // content model is also used for constructions such as:
-        //
-        //     (Optional*,NotRequired?)
-        //
-        // where a perfectly valid content would be NO CHILDREN.
-        // Therefore, if there are no children, we must check to
-        // see if the CMNODE_EOC marker is a valid start state! -Ac
-        //
-        if (length == 0) {
-            if (DEBUG_VALIDATE_CONTENT) {
-                System.out.println("!!! no children");
-                System.out.println("elemMap="+fElemMap);
-                for (int i = 0; i < fElemMap.length; i++) {
-                    int uriIndex = fElemMap[i].uri;
-                    int localpartIndex = fElemMap[i].localpart;
-                    /*
-                    System.out.println("fElemMap["+i+"]="+uriIndex+","+
-                                       localpartIndex+" ("+
-                                       fStringPool.toString(uriIndex)+", "+
-                                       fStringPool.toString(localpartIndex)+
-                                       ')');
-                                       */
-                }
-                System.out.println("EOCIndex="+fEOCIndex);
-            }
-
-            return fEmptyContentIsValid ? -1 : 0;
-
-        } // if child count == 0
-
-        //
-        //  Lets loop through the children in the array and move our way
-        //  through the states. Note that we use the fElemMap array to map
-        //  an element index to a state index.
-        //
-        int curState = 0;
-        for (int childIndex = 0; childIndex < length; childIndex++)
-        {
-            // Get the current element index out
-            final QName curElem = children[offset + childIndex];
-            //System.out.println("children["+(offset+childIndex)+"]: "+curElem);
-
-            // Look up this child in our element map
-            int elemIndex = 0;
-            for (; elemIndex < fElemMapSize; elemIndex++)
-            {
-                int type = fElemMapType[elemIndex] & 0x0f ;
-                if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-                    //System.out.println("fElemMap["+elemIndex+"]: "+fElemMap[elemIndex]);
-                    if (fDTD) {
-                        if (fElemMap[elemIndex].rawname == curElem.rawname) {
-                            break;
-                        }
-                    }
-                    else {
-                        if (fElemMap[elemIndex].uri==curElem.uri
-                             && fElemMap[elemIndex].localpart == curElem.localpart)
-                            break;
-                    }
-                }
-                else if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
-                    int uri = fElemMap[elemIndex].uri;
-                    if (uri == -1 || uri == curElem.uri) {
-                        break;
-                    }
-                }
-                else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
-                    if (curElem.uri == -1) {
-                        break;
-                    }
-                }
-                else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
-                    if (fElemMap[elemIndex].uri != curElem.uri) {
-                        break;
-                    }
-                }
-            }
-
-            // If we didn't find it, then obviously not valid
-            if (elemIndex == fElemMapSize) {
-                if (DEBUG_VALIDATE_CONTENT) {
-                    System.out.println("!!! didn't find it");
-
-                    System.out.println("curElem : " +curElem );
-                    for (int i=0; i<fElemMapSize; i++) {
-                        System.out.println("fElemMap["+i+"] = " +fElemMap[i] );
-                        System.out.println("fElemMapType["+i+"] = " +fElemMapType[i] );
-                    }
-                }
-
-                return childIndex;
-            }
-
-            //
-            //  Look up the next state for this input symbol when in the
-            //  current state.
-            //
-            curState = fTransTable[curState][elemIndex];
-
-            // If its not a legal transition, then invalid
-            if (curState == -1) {
-                if (DEBUG_VALIDATE_CONTENT) 
-                    System.out.println("!!! not a legal transition");
-                return childIndex;
-            }
-        }
-
-        //
-        //  We transitioned all the way through the input list. However, that
-        //  does not mean that we ended in a final state. So check whether
-        //  our ending state is a final state.
-        //
-        if (DEBUG_VALIDATE_CONTENT) 
-            System.out.println("curState="+curState+", childCount="+length);
-        if (!fFinalStateFlags[curState])
-            return length;
-
-        // success!
-        return -1;
-    }
-
-    private boolean isEqual(QName name1, QName name2) {
-            return name1.localpart == name2.localpart &&
-                name1.uri == name2.uri;
-    }
-    
-    public int validateContentSpecial(QName children[], int offset, int length) throws Exception{
-        if (DEBUG_VALIDATE_CONTENT) 
-            System.out.println("DFAContentModel#validateContentSpecial");
-
-        if (comparator==null) {
-            return validateContent(children,offset, length);
-        }
-
-
-        if (length == 0) {
-            if (DEBUG_VALIDATE_CONTENT) {
-                System.out.println("!!! no children");
-                System.out.println("elemMap="+fElemMap);
-                for (int i = 0; i < fElemMap.length; i++) {
-                    int uriIndex = fElemMap[i].uri;
-                    int localpartIndex = fElemMap[i].localpart;
-                }
-                System.out.println("EOCIndex="+fEOCIndex);
-            }
-
-            return fEmptyContentIsValid ? -1 : 0;
-
-        } // if child count == 0
-
-        //
-        //  Lets loop through the children in the array and move our way
-        //  through the states. Note that we use the fElemMap array to map
-        //  an element index to a state index.
-        //
-        int curState = 0;
-        for (int childIndex = 0; childIndex < length; childIndex++)
-        {
-            // Get the current element index out
-            final QName curElem = children[offset + childIndex];
-
-            // Look up this child in our element map
-            int elemIndex = 0;
-            for (; elemIndex < fElemMapSize; elemIndex++)
-            {
-                int type = fElemMapType[elemIndex] & 0x0f;
-                if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-                    if (comparator.isEquivalentTo(curElem,fElemMap[elemIndex] ) )
-                        break;
-                }
-                else if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
-                    int uri = fElemMap[elemIndex].uri;
-                    if (uri == -1 || uri == curElem.uri) {
-                        break;
-                    }
-                }
-                else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
-                    if (curElem.uri == -1) {
-                        break;
-                    }
-                }
-                else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
-                    if (fElemMap[elemIndex].uri != curElem.uri) {
-                        break;
-                    }
-                }
-            }
-
-            // If we didn't find it, then obviously not valid
-            if (elemIndex == fElemMapSize) {
-                if (DEBUG_VALIDATE_CONTENT) {
-                    System.out.println("!!! didn't find it");
-
-                    System.out.println("curElem : " +curElem );
-                    for (int i=0; i<fElemMapSize; i++) {
-                        System.out.println("fElemMap["+i+"] = " +fElemMap[i] );
-                        System.out.println("fElemMapType["+i+"] = " +fElemMapType[i] );
-                    }
-                }
-
-                return childIndex;
-            }
-
-            //
-            //  Look up the next state for this input symbol when in the
-            //  current state.
-            //
-            curState = fTransTable[curState][elemIndex];
-
-            // If its not a legal transition, then invalid
-            if (curState == -1) {
-                if (DEBUG_VALIDATE_CONTENT) 
-                    System.out.println("!!! not a legal transition");
-                return childIndex;
-            }
-        }
-
-        //
-        //  We transitioned all the way through the input list. However, that
-        //  does not mean that we ended in a final state. So check whether
-        //  our ending state is a final state.
-        //
-        if (DEBUG_VALIDATE_CONTENT) 
-            System.out.println("curState="+curState+", childCount="+length);
-        if (!fFinalStateFlags[curState])
-            return length;
-
-        // success!
-        return -1;
-    }
-
-    public void setEquivClassComparator(EquivClassComparator comparator) {
-        this.comparator = comparator;
-    }
-
-    /**
-     * Returns information about which elements can be placed at a particular point
-     * in the passed element's content model.
-     * <p>
-     * Note that the incoming content model to test must be valid at least up to
-     * the insertion point. If not, then -1 will be returned and the info object
-     * will not have been filled in.
-     * <p>
-     * If, on return, the info.isValidEOC flag is set, then the 'insert after'
-     * element is a valid end of content. In other words, nothing needs to be
-     * inserted after it to make the parent element's content model valid.
-     *
-     * @param fullyValid Only return elements that can be inserted and still
-     *                   maintain the validity of subsequent elements past the
-     *                   insertion point (if any).  If the insertion point is at
-     *                   the end, and this is true, then only elements that can
-     *                   be legal final states will be returned.
-     * @param info An object that contains the required input data for the method,
-     *             and which will contain the output information if successful.
-     *
-     * @return The value -1 if fully valid, else the 0 based index of the child
-     *         that first failed before the insertion point. If the value 
-     *         returned is equal to the number of children, then the specified
-     *         children are valid but additional content is required to reach a
-     *         valid ending state.
-     *
-     * @see InsertableElementsInfo
-     */
-    public int whatCanGoHere(boolean fullyValid, 
-                             InsertableElementsInfo info) throws CMException {
-
-        //
-        //  First, lets make sure that the passed in current content is valid
-        //  up to the insert point.
-        //
-        int curState = 0;
-        for (int childIndex = 0; childIndex < info.insertAt; childIndex++)
-        {
-            // Get the current element index out
-            final QName curElem = info.curChildren[childIndex];
-
-            // Look up this child in our element map
-            int elemIndex = 0;
-            for (; elemIndex < fElemMapSize; elemIndex++)
-            {
-                if (fElemMap[elemIndex].uri == curElem.uri && 
-                    fElemMap[elemIndex].localpart == curElem.localpart)
-                    break;
-            }
-
-            // If we didn't find it, then not valid so return failure index
-            if (elemIndex == fElemMapSize)
-                return childIndex;
-
-            //
-            //  Look up the next state for this input symbol when in the
-            //  current state.
-            //
-            curState = fTransTable[curState][elemIndex];
-
-            // If its not a legal transition, then invalid
-            if (curState == -1)
-                return childIndex;
-        }
-
-        //
-        //  If we got here, then curState is set to the state that would be
-        //  the transition before the insertion point. We let this sit until
-        //  below, where it will be needed.
-        //
-        final int insertState = curState;
-
-        //
-        //  Set any stuff we can know right off the bat for all cases. We know
-        //  that this content model will never get PCData nodes because that
-        //  is a mixed model. We can also set the valid EOC flag at this point
-        //  since its just based on the state we ended in at the insert point.
-        //
-        info.canHoldPCData = false;
-        info.isValidEOC = fFinalStateFlags[insertState];
-
-        //
-        //  Set the results count member and then see if we need to reallocate
-        //  the outgoing arrays.
-        //
-        info.resultsCount = fElemMapSize;
-
-        if ((info.results == null) || (info.results.length < info.resultsCount))
-            info.results = new boolean[info.resultsCount];
-
-        if ((info.possibleChildren == null)
-        ||  (info.possibleChildren.length < info.resultsCount))
-        {
-            info.possibleChildren = new QName[info.resultsCount];
-            for (int i = 0; i < info.possibleChildren.length; i++) {
-                info.possibleChildren[i] = new QName();
-            }
-        }
-
-        //
-        //  Fill in the possible children array, from our array. For each one
-        //  of them, see if there is a valid transition from our insert at
-        //  state on that input. Mark the results index for that child according
-        //  to whether there is a transition or not.
-        //
-        for (int index = 0; index < fElemMapSize; index++)
-        {
-            info.possibleChildren[index].setValues(fElemMap[index]);
-            info.results[index] = (fTransTable[insertState][index] != -1);
-        }
-
-        //
-        //  If the fully valid parameter is set, then we have to go through
-        //  the grunt work of plugging in each possible insertable element
-        //  and running the DFA from that point to see if it would create a
-        //  fully valid content model.
-        //
-        //  <TBD> When/if the validator is changed to be stateful, then change
-        //  this stuff to start the exploratory validation at the insert state,
-        //  not from the start each time.
-        //
-        if (fullyValid)
-        {
-            for (int index = 0; index < info.resultsCount; index++)
-            {
-                // Don't need to consider this one since its not insertable
-                if (!info.results[index])
-                    continue;
-
-                // Stick this element into the insert at spot
-                info.curChildren[info.insertAt] = info.possibleChildren[index];
-
-                // And validate it. If it fails, then this one loses
-                if (validateContent(info.curChildren, 0, info.childCount) != -1)
-                    info.results[index] = false;
-            }
-        }
-
-        return -1;
-    }
-
-    public ContentLeafNameTypeVector getContentLeafNameTypeVector() {
-        return fLeafNameTypeVector;
-    }
-
-    //
-    // Private methods
-    //
-
-    /** 
-     * Builds the internal DFA transition table from the given syntax tree.
-     *
-     * @param syntaxTree The syntax tree.
-     *
-     * @exception CMException Thrown if DFA cannot be built.
-     */
-    private void buildDFA(CMNode syntaxTree) throws CMException
-    {
-        //
-        //  The first step we need to take is to rewrite the content model
-        //  using our CMNode objects, and in the process get rid of any
-        //  repetition short cuts, converting them into '*' style repetitions
-        //  or getting rid of repetitions altogether.
-        //
-        //  The conversions done are:
-        //
-        //  x+ -> (x|x*)
-        //  x? -> (x|epsilon)
-        //
-        //  This is a relatively complex scenario. What is happening is that
-        //  we create a top level binary node of which the special EOC value
-        //  is set as the right side node. The the left side is set to the
-        //  rewritten syntax tree. The source is the original content model
-        //  info from the decl pool. The rewrite is done by buildSyntaxTree()
-        //  which recurses the decl pool's content of the element and builds
-        //  a new tree in the process.
-        //
-        //  Note that, during this operation, we set each non-epsilon leaf
-        //  node's DFA state position and count the number of such leafs, which
-        //  is left in the fLeafCount member.
-        //
-        //  The nodeTmp object is passed in just as a temp node to use during
-        //  the recursion. Otherwise, we'd have to create a new node on every
-        //  level of recursion, which would be piggy in Java (as is everything
-        //  for that matter.)
-        //
-        fQName.setValues(-1, fEOCIndex, fEOCIndex);
-        CMLeaf nodeEOC = new CMLeaf(fQName);
-        fHeadNode = new CMBinOp
-        (
-            XMLContentSpec.CONTENTSPECNODE_SEQ
-            , syntaxTree
-            , nodeEOC
-        );
-
-        //
-        //  And handle specially the EOC node, which also must be numbered
-        //  and counted as a non-epsilon leaf node. It could not be handled
-        //  in the above tree build because it was created before all that
-        //  started. We save the EOC position since its used during the DFA
-        //  building loop.
-        //
-        fEOCPos = fLeafCount;
-        nodeEOC.setPosition(fLeafCount++);
-
-        //
-        //  Ok, so now we have to iterate the new tree and do a little more
-        //  work now that we know the leaf count. One thing we need to do is
-        //  to calculate the first and last position sets of each node. This
-        //  is cached away in each of the nodes.
-        //
-        //  Along the way we also set the leaf count in each node as the
-        //  maximum state count. They must know this in order to create their
-        //  first/last pos sets.
-        //
-        //  We also need to build an array of references to the non-epsilon
-        //  leaf nodes. Since we iterate it in the same way as before, this
-        //  will put them in the array according to their position values.
-        //
-        fLeafList = new CMLeaf[fLeafCount];
-        fLeafListType = new int[fLeafCount];
-        postTreeBuildInit(fHeadNode, 0);
-
-        //
-        //  And, moving onward... We now need to build the follow position
-        //  sets for all the nodes. So we allocate an array of state sets,
-        //  one for each leaf node (i.e. each DFA position.)
-        //
-        fFollowList = new CMStateSet[fLeafCount];
-        for (int index = 0; index < fLeafCount; index++)
-            fFollowList[index] = new CMStateSet(fLeafCount);
-        calcFollowList(fHeadNode);
-        //
-        //  And finally the big push... Now we build the DFA using all the
-        //  states and the tree we've built up. First we set up the various
-        //  data structures we are going to use while we do this.
-        //
-        //  First of all we need an array of unique element names in our
-        //  content model. For each transition table entry, we need a set of
-        //  contiguous indices to represent the transitions for a particular
-        //  input element. So we need to a zero based range of indexes that
-        //  map to element types. This element map provides that mapping.
-        //
-        fElemMap = new QName[fLeafCount];
-        fElemMapType = new int[fLeafCount];
-        fElemMapSize = 0;
-        for (int outIndex = 0; outIndex < fLeafCount; outIndex++)
-        {
-            fElemMap[outIndex] = new QName();
-
-            if ( (fLeafListType[outIndex] & 0x0f) != 0 ) {
-                if (fLeafNameTypeVector == null) {
-                    fLeafNameTypeVector = new ContentLeafNameTypeVector();
-                }
-            }
-
-            // Get the current leaf's element index
-            final QName element = fLeafList[outIndex].getElement();
-
-            // See if the current leaf node's element index is in the list
-            int inIndex = 0;
-            for (; inIndex < fElemMapSize; inIndex++)
-            {
-                if (fDTD) {
-                    if (fElemMap[inIndex].rawname == element.rawname) {
-                        break;
-                    }
-                }
-                else {
-                    if (fElemMap[inIndex].uri == element.uri &&
-                        fElemMap[inIndex].localpart == element.localpart && 
-                        fElemMapType[inIndex] == fLeafListType[outIndex] )
-                        break;
-                }
-            }
-
-            // If it was not in the list, then add it, if not the EOC node
-            if (inIndex == fElemMapSize) {
-                //if (fDTD) {
-                //    fElemMap[fElemMapSize].setValues(-1, element.rawname, element.rawname, -1);
-                //}
-                //else {
-                    fElemMap[fElemMapSize].setValues(element);
-                //}
-                fElemMapType[fElemMapSize] = fLeafListType[outIndex];
-                fElemMapSize++;
-            }
-        }
-        // set up the fLeafNameTypeVector object if there is one.
-        if (fLeafNameTypeVector != null) {
-            fLeafNameTypeVector.setValues(fElemMap, fElemMapType, fElemMapSize);
-        }
-
-        //
-        //  Next lets create some arrays, some that that hold transient
-        //  information during the DFA build and some that are permament.
-        //  These are kind of sticky since we cannot know how big they will
-        //  get, but we don't want to use any Java collections because of
-        //  performance.
-        //
-        //  Basically they will probably be about fLeafCount*2 on average,
-        //  but can be as large as 2^(fLeafCount*2), worst case. So we start
-        //  with fLeafCount*4 as a middle ground. This will be very unlikely
-        //  to ever have to expand, though it if does, the overhead will be
-        //  somewhat ugly.
-        //
-        int curArraySize = fLeafCount * 4;
-        CMStateSet[] statesToDo = new CMStateSet[curArraySize];
-        fFinalStateFlags = new boolean[curArraySize];
-        fTransTable = new int[curArraySize][];
-
-        //
-        //  Ok we start with the initial set as the first pos set of the
-        //  head node (which is the seq node that holds the content model
-        //  and the EOC node.)
-        //
-        CMStateSet setT = fHeadNode.firstPos();
-
-        //
-        //  Init our two state flags. Basically the unmarked state counter
-        //  is always chasing the current state counter. When it catches up,
-        //  that means we made a pass through that did not add any new states
-        //  to the lists, at which time we are done. We could have used a
-        //  expanding array of flags which we used to mark off states as we
-        //  complete them, but this is easier though less readable maybe.
-        //
-        int unmarkedState = 0;
-        int curState = 0;
-
-        //
-        //  Init the first transition table entry, and put the initial state
-        //  into the states to do list, then bump the current state.
-        //
-        fTransTable[curState] = makeDefStateList();
-        statesToDo[curState] = setT;
-        curState++;
-
-        //
-        //  Ok, almost done with the algorithm... We now enter the
-        //  loop where we go until the states done counter catches up with
-        //  the states to do counter.
-        //
-        while (unmarkedState < curState)
-        {
-            //
-            //  Get the first unmarked state out of the list of states to do.
-            //  And get the associated transition table entry.
-            //
-            setT = statesToDo[unmarkedState];
-            int[] transEntry = fTransTable[unmarkedState];
-
-            // Mark this one final if it contains the EOC state
-            fFinalStateFlags[unmarkedState] = setT.getBit(fEOCPos);
-
-            // Bump up the unmarked state count, marking this state done
-            unmarkedState++;
-
-            // Loop through each possible input symbol in the element map
-            CMStateSet newSet = null;
-            for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++)
-            {
-                //
-                //  Build up a set of states which is the union of all of
-                //  the follow sets of DFA positions that are in the current
-                //  state. If we gave away the new set last time through then
-                //  create a new one. Otherwise, zero out the existing one.
-                //
-                if (newSet == null)
-                    newSet = new CMStateSet(fLeafCount);
-                else
-                    newSet.zeroBits();
-
-                for (int leafIndex = 0; leafIndex < fLeafCount; leafIndex++)
-                {
-                    // If this leaf index (DFA position) is in the current set...
-                    if (setT.getBit(leafIndex))
-                    {
-                        //
-                        //  If this leaf is the current input symbol, then we
-                        //  want to add its follow list to the set of states to
-                        //  transition to from the current state.
-                        //
-                        final QName leaf = fLeafList[leafIndex].getElement();
-                        final QName element = fElemMap[elemIndex];
-                        if (fDTD) {
-                            if (leaf.rawname == element.rawname) {
-                                newSet.union(fFollowList[leafIndex]);
-                            }
-                        }
-                        else {
-                            if (leaf.uri == element.uri &&
-                                leaf.localpart == element.localpart)
-                                newSet.union(fFollowList[leafIndex]);
-                        }
-                    }
-                }
-
-                //
-                //  If this new set is not empty, then see if its in the list
-                //  of states to do. If not, then add it.
-                //
-                if (!newSet.isEmpty())
-                {
-                    //
-                    //  Search the 'states to do' list to see if this new
-                    //  state set is already in there.
-                    //
-                    int stateIndex = 0;
-                    for (; stateIndex < curState; stateIndex++)
-                    {
-                        if (statesToDo[stateIndex].isSameSet(newSet))
-                            break;
-                    }
-
-                    // If we did not find it, then add it
-                    if (stateIndex == curState)
-                    {
-                        //
-                        //  Put this new state into the states to do and init
-                        //  a new entry at the same index in the transition
-                        //  table.
-                        //
-                        statesToDo[curState] = newSet;
-                        fTransTable[curState] = makeDefStateList();
-
-                        // We now have a new state to do so bump the count
-                        curState++;
-
-                        //
-                        //  Null out the new set to indicate we adopted it.
-                        //  This will cause the creation of a new set on the
-                        //  next time around the loop.
-                        //
-                        newSet = null;
-                    }
-
-                    //
-                    //  Now set this state in the transition table's entry
-                    //  for this element (using its index), with the DFA
-                    //  state we will move to from the current state when we
-                    //  see this input element.
-                    //
-                    transEntry[elemIndex] = stateIndex;
-
-                    // Expand the arrays if we're full
-                    if (curState == curArraySize)
-                    {
-                        //
-                        //  Yikes, we overflowed the initial array size, so
-                        //  we've got to expand all of these arrays. So adjust
-                        //  up the size by 50% and allocate new arrays.
-                        //
-                        final int newSize = (int)(curArraySize * 1.5);
-                        CMStateSet[] newToDo = new CMStateSet[newSize];
-                        boolean[] newFinalFlags = new boolean[newSize];
-                        int[][] newTransTable = new int[newSize][];
-
-                        // Copy over all of the existing content
-                        for (int expIndex = 0; expIndex < curArraySize; expIndex++)
-                        {
-                            newToDo[expIndex] = statesToDo[expIndex];
-                            newFinalFlags[expIndex] = fFinalStateFlags[expIndex];
-                            newTransTable[expIndex] = fTransTable[expIndex];
-                        }
-
-                        // Store the new array size
-                        curArraySize = newSize;
-                        statesToDo = newToDo;
-                        fFinalStateFlags = newFinalFlags;
-                        fTransTable = newTransTable;
-                    }
-                }
-            }
-        }
-
-        // Check to see if we can set the fEmptyContentIsValid flag.
-        fEmptyContentIsValid = ((CMBinOp)fHeadNode).getLeft().isNullable();
-
-        //
-        //  And now we can say bye bye to the temp representation since we've
-        //  built the DFA.
-        //
-        if (DEBUG_VALIDATE_CONTENT) 
-            dumpTree(fHeadNode, 0);
-        fHeadNode = null;
-        fLeafList = null;
-        fFollowList = null;
-
-    }
-
-    /**
-     * Calculates the follow list of the current node.
-     *
-     * @param nodeCur The curent node.
-     *
-     * @exception CMException Thrown if follow list cannot be calculated.
-     */
-    private void calcFollowList(CMNode nodeCur) throws CMException
-    {
-        // Recurse as required
-        if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_CHOICE)
-        {
-            // Recurse only
-            calcFollowList(((CMBinOp)nodeCur).getLeft());
-            calcFollowList(((CMBinOp)nodeCur).getRight());
-        }
-         else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_SEQ)
-        {
-            // Recurse first
-            calcFollowList(((CMBinOp)nodeCur).getLeft());
-            calcFollowList(((CMBinOp)nodeCur).getRight());
-
-            //
-            //  Now handle our level. We use our left child's last pos
-            //  set and our right child's first pos set, so go ahead and
-            //  get them ahead of time.
-            //
-            final CMStateSet last  = ((CMBinOp)nodeCur).getLeft().lastPos();
-            final CMStateSet first = ((CMBinOp)nodeCur).getRight().firstPos();
-
-            //
-            //  Now, for every position which is in our left child's last set
-            //  add all of the states in our right child's first set to the
-            //  follow set for that position.
-            //
-            for (int index = 0; index < fLeafCount; index++)
-            {
-                if (last.getBit(index))
-                    fFollowList[index].union(first);
-            }
-        }
-         else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
-        {
-            // Recurse first
-            calcFollowList(((CMUniOp)nodeCur).getChild());
-
-            //
-            //  Now handle our level. We use our own first and last position
-            //  sets, so get them up front.
-            //
-            final CMStateSet first = nodeCur.firstPos();
-            final CMStateSet last  = nodeCur.lastPos();
-
-            //
-            //  For every position which is in our last position set, add all
-            //  of our first position states to the follow set for that
-            //  position.
-            //
-            for (int index = 0; index < fLeafCount; index++)
-            {
-                if (last.getBit(index))
-                    fFollowList[index].union(first);
-            }
-        }
-         else if ((nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE)
-              ||  (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE))
-        {
-            throw new CMException(ImplementationMessages.VAL_NIICM);
-        }
-    }
-
-    /**
-     * Dumps the tree of the current node to standard output.
-     *
-     * @param nodeCur The current node.
-     * @param level   The maximum levels to output.
-     *
-     * @exception CMException Thrown on error.
-     */
-    private void dumpTree(CMNode nodeCur, int level) throws CMException
-    {
-        for (int index = 0; index < level; index++)
-            System.out.print("   ");
-
-        int type = nodeCur.type();
-        if ((type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
-        ||  (type == XMLContentSpec.CONTENTSPECNODE_SEQ))
-        {
-            if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
-                System.out.print("Choice Node ");
-            else
-                System.out.print("Seq Node ");
-
-            if (nodeCur.isNullable())
-                System.out.print("Nullable ");
-
-            System.out.print("firstPos=");
-            System.out.print(nodeCur.firstPos().toString());
-            System.out.print(" lastPos=");
-            System.out.println(nodeCur.lastPos().toString());
-
-            dumpTree(((CMBinOp)nodeCur).getLeft(), level+1);
-            dumpTree(((CMBinOp)nodeCur).getRight(), level+1);
-        }
-         else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
-        {
-            System.out.print("Rep Node ");
-
-            if (nodeCur.isNullable())
-                System.out.print("Nullable ");
-
-            System.out.print("firstPos=");
-            System.out.print(nodeCur.firstPos().toString());
-            System.out.print(" lastPos=");
-            System.out.println(nodeCur.lastPos().toString());
-
-            dumpTree(((CMUniOp)nodeCur).getChild(), level+1);
-        }
-         else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_LEAF)
-        {
-            System.out.print
-            (
-                "Leaf: (pos="
-                + ((CMLeaf)nodeCur).getPosition()
-                + "), "
-                + ((CMLeaf)nodeCur).getElement()
-                + "(elemIndex="
-                + ((CMLeaf)nodeCur).getElement()
-                + ") "
-            );
-
-            if (nodeCur.isNullable())
-                System.out.print(" Nullable ");
-
-            System.out.print("firstPos=");
-            System.out.print(nodeCur.firstPos().toString());
-            System.out.print(" lastPos=");
-            System.out.println(nodeCur.lastPos().toString());
-        }
-         else
-        {
-            throw new CMException(ImplementationMessages.VAL_NIICM);
-        }
-    }
-
-
-    /**
-     * -1 is used to represent bad transitions in the transition table
-     * entry for each state. So each entry is initialized to an all -1
-     * array. This method creates a new entry and initializes it.
-     */
-    private int[] makeDefStateList()
-    {
-        int[] retArray = new int[fElemMapSize];
-        for (int index = 0; index < fElemMapSize; index++)
-            retArray[index] = -1;
-        return retArray;
-    }
-
-    /** Post tree build initialization. */
-    private int postTreeBuildInit(CMNode nodeCur, int curIndex) throws CMException
-    {
-        // Set the maximum states on this node
-        nodeCur.setMaxStates(fLeafCount);
-
-        // Recurse as required
-        if ((nodeCur.type() & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY ||
-            (nodeCur.type() & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL ||
-            (nodeCur.type() & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
-            // REVISIT: Don't waste these structures.
-            QName qname = new QName(-1, -1, -1, ((CMAny)nodeCur).getURI());
-            fLeafList[curIndex] = new CMLeaf(qname, ((CMAny)nodeCur).getPosition());
-            fLeafListType[curIndex] = nodeCur.type();
-            curIndex++;
-        }
-        else if ((nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_CHOICE)
-        ||  (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_SEQ))
-        {
-            curIndex = postTreeBuildInit(((CMBinOp)nodeCur).getLeft(), curIndex);
-            curIndex = postTreeBuildInit(((CMBinOp)nodeCur).getRight(), curIndex);
-        }
-         else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
-        {
-            curIndex = postTreeBuildInit(((CMUniOp)nodeCur).getChild(), curIndex);
-        }
-         else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_LEAF)
-        {
-            //
-            //  Put this node in the leaf list at the current index if its
-            //  a non-epsilon leaf.
-            //
-             final QName node = ((CMLeaf)nodeCur).getElement();
-            if (node.localpart != fEpsilonIndex) {
-                fLeafList[curIndex] = (CMLeaf)nodeCur;
-                fLeafListType[curIndex] = XMLContentSpec.CONTENTSPECNODE_LEAF;
-                curIndex++;
-            }
-        }
-         else
-        {
-            throw new CMException(ImplementationMessages.VAL_NIICM);
-        }
-        return curIndex;
-    }
-
-
-} // class DFAContentModel
diff --git a/src/org/apache/xerces/validators/common/Grammar.java b/src/org/apache/xerces/validators/common/Grammar.java
deleted file mode 100644
index 69fe2fe..0000000
--- a/src/org/apache/xerces/validators/common/Grammar.java
+++ /dev/null
@@ -1,908 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.framework.XMLContentSpec;
-import org.apache.xerces.utils.Hash2intTable;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.validators.datatype.DatatypeValidator;
-import org.apache.xerces.validators.common.XMLContentModel;
-import org.apache.xerces.validators.common.CMException;
-import org.apache.xerces.utils.ImplementationMessages;
-import org.w3c.dom.Document;
-import java.util.Vector;
-
-
-/**
- * @version $Id$
- */
-public class Grammar
-implements XMLContentSpec.Provider {
-
-    //
-    // Constants
-    //
-
-    private static final int CHUNK_SHIFT = 8; // 2^8 = 256
-    private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
-    private static final int CHUNK_MASK = CHUNK_SIZE - 1;
-    private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
-
-    private static final int LIST_FLAG = 0x8000;
-    private static final int LIST_MASK = ~LIST_FLAG;
-
-    //
-    // Data
-    //
-
-    // basic information
-
-    private int fTargetNamespace;
-
-    private Document fGrammarDocument;
-
-    // element decl tables
-
-    private int fElementDeclCount = 0;
-    private QName fElementDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
-    private int fElementDeclType[][] = new int[INITIAL_CHUNK_COUNT][];
-    private DatatypeValidator fElementDeclDatatypeValidator[][] = new DatatypeValidator[INITIAL_CHUNK_COUNT][];
-    private int fElementDeclContentSpecIndex[][] = new int[INITIAL_CHUNK_COUNT][];
-    private XMLContentModel fElementDeclContentModelValidator[][] = new XMLContentModel[INITIAL_CHUNK_COUNT][];
-    private int fElementDeclFirstAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
-    private int fElementDeclLastAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
-
-    // content spec tables
-
-    private int fContentSpecCount = 0 ;
-    private int fContentSpecType[][] = new int[INITIAL_CHUNK_COUNT][];
-    private int fContentSpecValue[][] = new int[INITIAL_CHUNK_COUNT][];
-    private int fContentSpecOtherValue[][] = new int[INITIAL_CHUNK_COUNT][];
-
-    // attribute decl tables
-
-    private int fAttributeDeclCount = 0 ;
-    private QName fAttributeDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
-    private int   fAttributeDeclType[][] = new int[INITIAL_CHUNK_COUNT][];
-    private int   fAttributeDeclEnumeration[][] = new int[INITIAL_CHUNK_COUNT][];
-    private int   fAttributeDeclDefaultType[][] = new int[INITIAL_CHUNK_COUNT][];
-    private DatatypeValidator fAttributeDeclDatatypeValidator[][] = new DatatypeValidator[INITIAL_CHUNK_COUNT][];
-    private String fAttributeDeclDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][];
-    private int fAttributeDeclNextAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
-
-    // scope mapping tables
-
-    private Hash2intTable fElementNameAndScopeToElementDeclIndexMapping = new Hash2intTable();
-
-    // temp vars
-
-    private QName fQName1 = new QName();
-    private QName fQName2 = new QName();
-
-    //
-    // Public methods
-    //
-
-    public Document getGrammarDocument() {
-        return fGrammarDocument;
-    }
-
-    public int getElementDeclIndex(int localpartIndex, int scopeIndex) {
-        if ( localpartIndex > -1 && scopeIndex >-2 ) {
-            return fElementNameAndScopeToElementDeclIndexMapping.get(-1, localpartIndex, scopeIndex);
-        }
-        return -1;
-    }
-    
-    public int getElementDeclIndex(int uriIndex, int localpartIndex, int scopeIndex) {
-        if ( localpartIndex > -1 && scopeIndex >-2 ) {
-            return fElementNameAndScopeToElementDeclIndexMapping.get(uriIndex, localpartIndex, scopeIndex);
-        }
-        return -1;
-    }
-    
-    public int getElementDeclIndex(QName element, int scopeIndex) {
-        if ( element.localpart > -1 && scopeIndex >-2 ) {
-            return fElementNameAndScopeToElementDeclIndexMapping.get(element.uri, element.localpart, scopeIndex);
-        }
-        return -1;
-    }
-
-    public boolean getElementDecl(int elementDeclIndex, XMLElementDecl elementDecl) {
-        if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
-            return false;
-        }
-
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex &  CHUNK_MASK;
-
-        elementDecl.name.setValues(fElementDeclName[chunk][index]);
-        if (fElementDeclType[chunk][index] == -1) {
-            elementDecl.type                    = -1;
-            elementDecl.list = false;
-        }
-        else {
-            elementDecl.type                    = fElementDeclType[chunk][index] & LIST_MASK;
-            elementDecl.list = (fElementDeclType[chunk][index] & LIST_FLAG) != 0;
-        }
-        elementDecl.datatypeValidator       = fElementDeclDatatypeValidator[chunk][index];       
-        elementDecl.contentSpecIndex        = fElementDeclContentSpecIndex[chunk][index];        
-
-        return true;
-    }
-
-    public int getFirstAttributeDeclIndex(int elementDeclIndex) {
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex &  CHUNK_MASK;
-
-        return  fElementDeclFirstAttributeDeclIndex[chunk][index];
-    }
-
-    public int getNextAttributeDeclIndex(int attributeDeclIndex) {
-        int chunk = attributeDeclIndex >> CHUNK_SHIFT;
-        int index = attributeDeclIndex &  CHUNK_MASK;
-
-        return fAttributeDeclNextAttributeDeclIndex[chunk][index];
-    }
-
-    public boolean getContentSpec(int contentSpecIndex, XMLContentSpec contentSpec) {
-        if (contentSpecIndex < 0 || contentSpecIndex >= fContentSpecCount )
-            return false;
-
-        int chunk = contentSpecIndex >> CHUNK_SHIFT;
-        int index = contentSpecIndex & CHUNK_MASK;
-
-        contentSpec.type       = fContentSpecType[chunk][index];
-        contentSpec.value      = fContentSpecValue[chunk][index];
-        contentSpec.otherValue = fContentSpecOtherValue[chunk][index];
-        return true;
-    }
-
-    public XMLContentModel getElementContentModel(int elementDeclIndex) throws CMException {
-
-        if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount)
-            return null;
-
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-
-        XMLContentModel contentModel    =  fElementDeclContentModelValidator[chunk][index];
-
-        // If we have one, just return that. Otherwise, gotta create one
-        if (contentModel != null)
-            return contentModel;
-
-        int contentType = fElementDeclType[chunk][index];
-        if (contentType == XMLElementDecl.TYPE_SIMPLE) {
-            return null;
-        }
-
-        // Get the type of content this element has
-
-        int contentSpecIndex = fElementDeclContentSpecIndex[chunk][index]; 
-
-        /***
-        if ( contentSpecIndex == -1 )
-            return null;
-        /***/
-
-        XMLContentSpec  contentSpec = new XMLContentSpec();
-        getContentSpec( contentSpecIndex, contentSpec );
-        
-        // And create the content model according to the spec type
-        
-        if ( contentType == XMLElementDecl.TYPE_MIXED ) {
-            //
-            //  Just create a mixel content model object. This type of
-            //  content model is optimized for mixed content validation.
-            //
-
-            Vector vQName = new Vector(); 
-            try {
-                ChildrenList children = new ChildrenList();
-                contentSpecTree(contentSpecIndex, contentSpec, children);
-                contentModel = new MixedContentModel(children.qname,
-                                                     children.type,
-                                                     0, children.length, false, isDTD());
-            }catch(  CMException ex ){
-                ex.printStackTrace();
-            }
-
-        } else if (contentType == XMLElementDecl.TYPE_CHILDREN) {
-            //  This method will create an optimal model for the complexity
-            //  of the element's defined model. If its simple, it will create
-            //  a SimpleContentModel object. If its a simple list, it will
-            //  create a SimpleListContentModel object. If its complex, it
-            //  will create a DFAContentModel object.
-            //
-            try {
-            contentModel = createChildModel(contentSpecIndex);
-            }catch( CMException ex ) {
-                 ex.printStackTrace();
-            }
-        } else {
-            throw new CMException(ImplementationMessages.VAL_CST);
-        }
-
-        // Add the new model to the content model for this element
-
-        fElementDeclContentModelValidator[chunk][index] = contentModel;
-
-        //build it  ..... in XMLValidator
-        return contentModel;
-    }
-
-
-
-    public boolean getAttributeDecl(int attributeDeclIndex, XMLAttributeDecl attributeDecl) {
-        if (attributeDeclIndex < 0 || attributeDeclIndex >= fAttributeDeclCount) {
-            return false;
-        }
-        int chunk = attributeDeclIndex >> CHUNK_SHIFT;
-        int index = attributeDeclIndex & CHUNK_MASK;
-
-        attributeDecl.name.setValues(fAttributeDeclName[chunk][index]);
-
-        if (fAttributeDeclType[chunk][index] == -1) {
-            
-            attributeDecl.type = -1;
-            attributeDecl.list = false;
-        }
-        else {
-            attributeDecl.type = fAttributeDeclType[chunk][index] & LIST_MASK;
-            attributeDecl.list = (fAttributeDeclType[chunk][index] & LIST_FLAG) != 0;
-        }
-        attributeDecl.datatypeValidator = fAttributeDeclDatatypeValidator[chunk][index];
-        attributeDecl.enumeration = fAttributeDeclEnumeration[chunk][index];
-        attributeDecl.defaultType = fAttributeDeclDefaultType[chunk][index];
-        attributeDecl.defaultValue = fAttributeDeclDefaultValue[chunk][index];
-        return true;
-    }
-
-    //
-    // Protected methods
-    //
-
-    protected void setGrammarDocument(Document grammarDocument) {
-        fGrammarDocument = grammarDocument;
-    }
-
-    protected int createElementDecl() {
-
-        int chunk = fElementDeclCount >> CHUNK_SHIFT;
-        int index = fElementDeclCount & CHUNK_MASK;
-        ensureElementDeclCapacity(chunk);
-        fElementDeclName[chunk][index]               = new QName(); 
-        fElementDeclType[chunk][index]                    = -1;  
-        fElementDeclDatatypeValidator[chunk][index]       = null;
-        fElementDeclContentSpecIndex[chunk][index] = -1;
-        fElementDeclContentModelValidator[chunk][index] = null;
-        fElementDeclFirstAttributeDeclIndex[chunk][index] = -1;
-        fElementDeclLastAttributeDeclIndex[chunk][index]  = -1;
-        return fElementDeclCount++;
-    }
-
-    protected void setElementDecl(int elementDeclIndex, XMLElementDecl elementDecl) {
-
-        if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
-            return;
-        }
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex &  CHUNK_MASK;
-
-        fElementDeclName[chunk][index].setValues(elementDecl.name);
-        fElementDeclType[chunk][index]                    = elementDecl.type;
-        if (elementDecl.list) {
-            fElementDeclType[chunk][index] |= LIST_FLAG;
-        }
-        fElementDeclDatatypeValidator[chunk][index]       = elementDecl.datatypeValidator;
-        fElementDeclContentSpecIndex[chunk][index]        = elementDecl.contentSpecIndex;
-
-        // add the mapping information to the 
-        putElementNameMapping(elementDecl.name,
-                              elementDecl.enclosingScope, 
-                              elementDeclIndex);
-    }
-
-    protected void putElementNameMapping(QName name, int scope,
-                                         int elementDeclIndex) {
-        fElementNameAndScopeToElementDeclIndexMapping.put(name.uri, 
-                                                          name.localpart, 
-                                                          scope,
-                                                          elementDeclIndex);
-    }
-
-    protected void setFirstAttributeDeclIndex(int elementDeclIndex, int newFirstAttrIndex){
-        
-        if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
-            return;
-        }
-    
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex &  CHUNK_MASK;
-
-        fElementDeclFirstAttributeDeclIndex[chunk][index] = newFirstAttrIndex;
-    }
-
-
-    protected int createContentSpec() {
-        int chunk = fContentSpecCount >> CHUNK_SHIFT;
-        int index = fContentSpecCount & CHUNK_MASK;
-
-        ensureContentSpecCapacity(chunk);
-        fContentSpecType[chunk][index]       = -1;
-        fContentSpecValue[chunk][index]      = -1;
-        fContentSpecOtherValue[chunk][index] = -1;
-
-        return fContentSpecCount++;
-    }
-
-    protected void setContentSpec(int contentSpecIndex, XMLContentSpec contentSpec) {
-        int   chunk = contentSpecIndex >> CHUNK_SHIFT;
-        int   index = contentSpecIndex & CHUNK_MASK;
-
-        fContentSpecType[chunk][index]       = contentSpec.type;
-        fContentSpecValue[chunk][index]      = contentSpec.value;
-        fContentSpecOtherValue[chunk][index] = contentSpec.otherValue;
-    }
-
-    protected int createAttributeDecl() {
-        int chunk = fAttributeDeclCount >> CHUNK_SHIFT;
-        int index = fAttributeDeclCount & CHUNK_MASK;
-
-        ensureAttributeDeclCapacity(chunk);
-        fAttributeDeclName[chunk][index]                    = new QName();
-        fAttributeDeclType[chunk][index]                    = -1;
-        fAttributeDeclDatatypeValidator[chunk][index]       = null;
-        fAttributeDeclEnumeration[chunk][index] = -1;
-        fAttributeDeclDefaultType[chunk][index] = XMLAttributeDecl.DEFAULT_TYPE_IMPLIED;
-        fAttributeDeclDefaultValue[chunk][index]            = null;
-        fAttributeDeclNextAttributeDeclIndex[chunk][index]  = -1;
-        return fAttributeDeclCount++;
-    }
-
-
-    protected void setAttributeDecl(int elementDeclIndex, int attributeDeclIndex, XMLAttributeDecl attributeDecl) {
-
-        int attrChunk = attributeDeclIndex >> CHUNK_SHIFT;
-        int attrIndex = attributeDeclIndex &  CHUNK_MASK; 
-
-        fAttributeDeclName[attrChunk][attrIndex].setValues(attributeDecl.name);
-
-        fAttributeDeclType[attrChunk][attrIndex]  =  attributeDecl.type;
-        if (attributeDecl.list) {
-            fAttributeDeclType[attrChunk][attrIndex] |= LIST_FLAG;
-        }
-        fAttributeDeclEnumeration[attrChunk][attrIndex]  =  attributeDecl.enumeration;
-        fAttributeDeclDefaultType[attrChunk][attrIndex]  =  attributeDecl.defaultType;
-        fAttributeDeclDatatypeValidator[attrChunk][attrIndex] =  attributeDecl.datatypeValidator;
-        fAttributeDeclDefaultValue[attrChunk][attrIndex]      =  attributeDecl.defaultValue;
-
-        int elemChunk     = elementDeclIndex >> CHUNK_SHIFT;
-        int elemIndex     = elementDeclIndex &  CHUNK_MASK;
-        int index = fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex];
-        while (index != -1) {
-            if (index == attributeDeclIndex) {
-                break;
-            }
-            attrChunk = index >> CHUNK_SHIFT;
-            attrIndex = index & CHUNK_MASK;
-            index = fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex];
-        }
-        if (index == -1) {
-            if (fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] == -1) {
-                fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex;
-            }
-            else {
-                index = fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex];
-                attrChunk = index >> CHUNK_SHIFT;
-                attrIndex = index & CHUNK_MASK;
-                fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex] = attributeDeclIndex;
-            }
-            fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex;
-        }
-
-    }
-
-    protected boolean isDTD() {
-        return false;
-    }
-
-    // debugging
-
-    public void printElements(org.apache.xerces.utils.StringPool pool) {
-        int elementDeclIndex = 0;
-        XMLElementDecl elementDecl = new XMLElementDecl();
-        while (getElementDecl(elementDeclIndex++, elementDecl)) {
-            System.out.println("element decl: "+elementDecl.name+
-                               ", "+pool.toString(elementDecl.name.rawname)+
-                               ", "+XMLContentSpec.toString(this, pool, elementDecl.contentSpecIndex));
-        }
-    }
-
-    public void printAttributes(int elementDeclIndex) {
-        int attributeDeclIndex = getFirstAttributeDeclIndex(elementDeclIndex);
-        System.out.print(elementDeclIndex);
-        System.out.print(" [");
-        while (attributeDeclIndex != -1) {
-            System.out.print(' ');
-            System.out.print(attributeDeclIndex);
-            printAttribute(attributeDeclIndex);
-            attributeDeclIndex = getNextAttributeDeclIndex(attributeDeclIndex);
-            if (attributeDeclIndex != -1) {
-                System.out.print(",");
-            }
-        }
-        System.out.println(" ]");
-    }
-
-    //
-    // Private methods
-    //
-
-    // debugging
-
-    private void printAttribute(int attributeDeclIndex) {
-        XMLAttributeDecl attributeDecl = new XMLAttributeDecl();
-        if (getAttributeDecl(attributeDeclIndex, attributeDecl)) {
-            System.out.print(" { ");
-            System.out.print(attributeDecl.name.localpart);
-            System.out.print(" }");
-        }
-    }
-
-    // content models
-
-    //
-    //  When the element has a 'CHILDREN' model, this method is called to
-    //  create the content model object. It looks for some special case simple
-    //  models and creates SimpleContentModel objects for those. For the rest
-    //  it creates the standard DFA style model.
-    //
-    private final XMLContentModel createChildModel(int contentSpecIndex) throws CMException
-    {
-        //
-        //  Get the content spec node for the element we are working on.
-        //  This will tell us what kind of node it is, which tells us what
-        //  kind of model we will try to create.
-        //
-        XMLContentSpec contentSpec = new XMLContentSpec();
-
-
-        getContentSpec(contentSpecIndex, contentSpec);
-
-        if ((contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY ||
-            (contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER ||
-            (contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
-            // let fall through to build a DFAContentModel
-        }
-
-        else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-            //
-            //  Check that the left value is not -1, since any content model
-            //  with PCDATA should be MIXED, so we should not have gotten here.
-            //
-            if (contentSpec.value == -1 && contentSpec.otherValue == -1)
-                throw new CMException(ImplementationMessages.VAL_NPCD);
-
-            //
-            //  Its a single leaf, so its an 'a' type of content model, i.e.
-            //  just one instance of one element. That one is definitely a
-            //  simple content model.
-            //
-
-            fQName1.setValues(-1, contentSpec.value, contentSpec.value, contentSpec.otherValue);
-            return new SimpleContentModel(fQName1, null, contentSpec.type, isDTD());
-        } 
-        else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
-                   ||  (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
-            //
-            //  Lets see if both of the children are leafs. If so, then it
-            //  it has to be a simple content model
-            //
-            XMLContentSpec contentSpecLeft  = new XMLContentSpec();
-            XMLContentSpec contentSpecRight = new XMLContentSpec();
-
-            getContentSpec(contentSpec.value, contentSpecLeft);
-            getContentSpec(contentSpec.otherValue, contentSpecRight);
-
-            if ((contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF)
-                &&  (contentSpecRight.type == XMLContentSpec.CONTENTSPECNODE_LEAF)) {
-                //
-                //  Its a simple choice or sequence, so we can do a simple
-                //  content model for it.
-                //
-                fQName1.setValues(-1, contentSpecLeft.value, contentSpecLeft.value, contentSpecLeft.otherValue);
-                fQName2.setValues(-1, contentSpecRight.value, contentSpecRight.value, contentSpecRight.otherValue);
-                return new SimpleContentModel(fQName1, fQName2, contentSpec.type, isDTD());
-            }
-        } 
-        else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE)
-                   ||  (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
-                   ||  (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE)) {
-            //
-            //  Its a repetition, so see if its one child is a leaf. If so
-            //  its a repetition of a single element, so we can do a simple
-            //  content model for that.
-            //
-            XMLContentSpec contentSpecLeft = new XMLContentSpec();
-            getContentSpec(contentSpec.value, contentSpecLeft);
-
-            if (contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-                //
-                //  It is, so we can create a simple content model here that
-                //  will check for this repetition. We pass -1 for the unused
-                //  right node.
-                //
-                fQName1.setValues(-1, contentSpecLeft.value, contentSpecLeft.value, contentSpecLeft.otherValue);
-                return new SimpleContentModel(fQName1, null, contentSpec.type, isDTD());
-            }
-        } 
-        else {
-            throw new CMException(ImplementationMessages.VAL_CST);
-        }
-
-        //
-        //  Its not a simple content model, so here we have to create a DFA
-        //  for this element. So we create a DFAContentModel object. He
-        //  encapsulates all of the work to create the DFA.
-        //
-        
-        //int leafCount = countLeaves(contentSpecIndex);
-        fLeafCount = 0;
-        CMNode cmn    = buildSyntaxTree(contentSpecIndex, contentSpec);
-
-        // REVISIT: has to be fLeafCount because we convert x+ to x,x*, one more leaf
-        return new DFAContentModel(  cmn, fLeafCount, isDTD());
-    }
-
-    private void printSyntaxTree(CMNode cmn){
-        System.out.println("CMNode : " + cmn.type());
-
-        if (cmn.type() == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-            System.out.println( "     Leaf: " + ((CMLeaf)cmn).getElement());
-            return;
-        }
-        if (cmn instanceof CMBinOp) {
-            printSyntaxTree( ((CMBinOp)cmn).getLeft());
-            printSyntaxTree( ((CMBinOp)cmn).getRight());
-        }
-        if (cmn instanceof CMUniOp) {
-            printSyntaxTree( ((CMUniOp)cmn).getChild());
-        }
-        
-    }
-
-    
-    private int countLeaves(int contentSpecIndex) {
-        return countLeaves(contentSpecIndex, new XMLContentSpec());
-    }
-    
-    private int countLeaves(int contentSpecIndex, XMLContentSpec contentSpec) {
-        
-        if (contentSpecIndex == -1) {
-            return 0;
-        }
-        /****
-        int chunk = contentSpecIndex >> CHUNK_SHIFT;
-        int index = contentSpecIndex & CHUNK_MASK;
-        int type = fContentSpecType[chunk][index];
-        if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-            return 1;
-        }
-        int value = fContentSpecValue[chunk][index];
-        int otherValue = fContentSpecOtherValue[chunk][index];
-        return countLeaves(value) + countLeaves(otherValue);
-        /***/
-        getContentSpec(contentSpecIndex, contentSpec);
-        if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-            return 1;
-        }
-        int value = contentSpec.value;
-        int otherValue = contentSpec.otherValue;
-        return countLeaves(value, contentSpec) + countLeaves(otherValue, contentSpec);
-        /***/
-    }
-
-    private int fLeafCount = 0;
-    private int fEpsilonIndex = -1;
-    private final CMNode buildSyntaxTree(int startNode, XMLContentSpec contentSpec) throws CMException
-    {
-        // We will build a node at this level for the new tree
-        CMNode nodeRet = null;
-        getContentSpec(startNode, contentSpec);
-        if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY) {
-            //nodeRet = new CMAny(contentSpec.type, -1, fLeafCount++);
-            nodeRet = new CMAny(contentSpec.type, contentSpec.otherValue, fLeafCount++);
-        }
-        else if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
-            nodeRet = new CMAny(contentSpec.type, contentSpec.otherValue, fLeafCount++);
-        }
-        else if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
-            nodeRet = new CMAny(contentSpec.type, -1, fLeafCount++);
-        }
-        //
-        //  If this node is a leaf, then its an easy one. We just add it
-        //  to the tree.
-        //
-        else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-            //
-            //  Create a new leaf node, and pass it the current leaf count,
-            //  which is its DFA state position. Bump the leaf count after
-            //  storing it. This makes the positions zero based since we
-            //  store first and then increment.
-            //
-            fQName1.setValues(-1, contentSpec.value, contentSpec.value, contentSpec.otherValue);
-            nodeRet = new CMLeaf(fQName1, fLeafCount++);
-        } 
-        else {
-            //
-            //  Its not a leaf, so we have to recurse its left and maybe right
-            //  nodes. Save both values before we recurse and trash the node.
-            //
-            final int leftNode = contentSpec.value;
-            final int rightNode = contentSpec.otherValue;
-
-            if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
-                ||  (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
-                //
-                //  Recurse on both children, and return a binary op node
-                //  with the two created sub nodes as its children. The node
-                //  type is the same type as the source.
-                //
-
-                nodeRet = new CMBinOp( contentSpec.type, buildSyntaxTree(leftNode, contentSpec)
-                                       , buildSyntaxTree(rightNode, contentSpec));
-            } else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE) {
-                nodeRet = new CMUniOp( contentSpec.type, buildSyntaxTree(leftNode, contentSpec));
-            } else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) {
-                // Convert to (x|epsilon)
-                nodeRet = new CMBinOp( XMLContentSpec.CONTENTSPECNODE_CHOICE,
-                                       buildSyntaxTree(leftNode, contentSpec)
-                                       , new CMLeaf( new QName(-1,-2,-2,-1), fEpsilonIndex));
-            } else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
-                // Convert to (x,x*)
-                nodeRet = new CMBinOp( XMLContentSpec.CONTENTSPECNODE_SEQ, 
-                                       buildSyntaxTree(leftNode, contentSpec), 
-                                       new CMUniOp( XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE,
-                                                    buildSyntaxTree(leftNode, contentSpec) ));
-            } else {
-                throw new CMException(ImplementationMessages.VAL_CST);
-            }
-        }
-        // And return our new node for this level
-        return nodeRet;
-    }
-
-    /**
-     * Build a vector of valid QNames from Content Spec
-     * table.
-     * 
-     * @param contentSpecIndex
-     *               Content Spec index
-     * @param vectorQName
-     *               Array of QName
-     * @exception CMException
-     */
-    private void contentSpecTree(int contentSpecIndex, 
-                                XMLContentSpec contentSpec,
-                                ChildrenList children) throws CMException {
-
-        // Handle any and leaf nodes
-        getContentSpec( contentSpecIndex, contentSpec);
-        if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF ||
-            (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY ||
-            (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL ||
-            (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
-
-            // resize arrays, if needed
-            if (children.length == children.qname.length) {
-                QName[] newQName = new QName[children.length * 2];
-                System.arraycopy(children.qname, 0, newQName, 0, children.length);
-                children.qname = newQName;
-                int[] newType = new int[children.length * 2];
-                System.arraycopy(children.type, 0, newType, 0, children.length);
-                children.type = newType;
-            }
-
-            // save values and return length
-            children.qname[children.length] = new QName(-1, contentSpec.value, contentSpec.value, contentSpec.otherValue);
-            children.type[children.length] = contentSpec.type;
-            children.length++;
-            return;
-        }
-
-        //
-        //  Its not a leaf, so we have to recurse its left and maybe right
-        //  nodes. Save both values before we recurse and trash the node.
-        //
-        final int leftNode  = contentSpec.value;
-        final int rightNode = contentSpec.otherValue;
-
-        if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE ||
-            contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ) {
-            contentSpecTree(leftNode, contentSpec, children);
-            contentSpecTree(rightNode, contentSpec, children);
-            return;
-        } 
-
-        if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ||
-            contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
-            contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
-            contentSpecTree(leftNode, contentSpec, children);
-            return;
-        }
-
-        // error
-        throw new CMException(ImplementationMessages.VAL_CST);
-    }
-
-
-
-    // ensure capacity
-
-    private boolean ensureElementDeclCapacity(int chunk) {
-        try {
-            return fElementDeclName[chunk][0] == null;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            fElementDeclName = resize(fElementDeclName, fElementDeclName.length * 2);
-            fElementDeclType = resize(fElementDeclType, fElementDeclType.length * 2);
-            fElementDeclDatatypeValidator = resize(fElementDeclDatatypeValidator, fElementDeclDatatypeValidator.length * 2);
-            fElementDeclContentSpecIndex = resize(fElementDeclContentSpecIndex, fElementDeclContentSpecIndex.length * 2);
-            fElementDeclContentModelValidator = resize(fElementDeclContentModelValidator, fElementDeclContentModelValidator.length * 2);
-            fElementDeclFirstAttributeDeclIndex = resize(fElementDeclFirstAttributeDeclIndex, fElementDeclFirstAttributeDeclIndex.length * 2);
-            fElementDeclLastAttributeDeclIndex = resize(fElementDeclLastAttributeDeclIndex, fElementDeclLastAttributeDeclIndex.length * 2);
-        } catch (NullPointerException ex) {
-            // ignore
-        }
-        fElementDeclName[chunk] = new QName[CHUNK_SIZE];
-        fElementDeclType[chunk] = new int[CHUNK_SIZE];
-        fElementDeclDatatypeValidator[chunk] = new DatatypeValidator[CHUNK_SIZE];
-        fElementDeclContentSpecIndex[chunk] = new int[CHUNK_SIZE];
-        fElementDeclContentModelValidator[chunk] = new XMLContentModel[CHUNK_SIZE];
-        fElementDeclFirstAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
-        fElementDeclLastAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
-        return true;
-    }
-
-    private boolean ensureContentSpecCapacity(int chunk) {
-        try {
-            return fContentSpecType[chunk][0] == 0;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            fContentSpecType = resize(fContentSpecType, fContentSpecType.length * 2);
-            fContentSpecValue = resize(fContentSpecValue, fContentSpecValue.length * 2);
-            fContentSpecOtherValue = resize(fContentSpecOtherValue, fContentSpecOtherValue.length * 2);
-        } catch (NullPointerException ex) {
-            // ignore
-        }
-        fContentSpecType[chunk] = new int[CHUNK_SIZE];
-        fContentSpecValue[chunk] = new int[CHUNK_SIZE];
-        fContentSpecOtherValue[chunk] = new int[CHUNK_SIZE];
-        return true;
-    }
-
-    private boolean ensureAttributeDeclCapacity(int chunk) {
-        try {
-            return fAttributeDeclName[chunk][0] == null;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            fAttributeDeclName = resize(fAttributeDeclName, fAttributeDeclName.length * 2);
-            fAttributeDeclType = resize(fAttributeDeclType, fAttributeDeclType.length * 2);
-            fAttributeDeclEnumeration = resize(fAttributeDeclEnumeration, fAttributeDeclEnumeration.length * 2);
-            fAttributeDeclDefaultType = resize(fAttributeDeclDefaultType, fAttributeDeclDefaultType.length * 2);
-            fAttributeDeclDatatypeValidator = resize(fAttributeDeclDatatypeValidator, fAttributeDeclDatatypeValidator.length * 2);
-            fAttributeDeclDefaultValue = resize(fAttributeDeclDefaultValue, fAttributeDeclDefaultValue.length * 2);
-            fAttributeDeclNextAttributeDeclIndex = resize(fAttributeDeclNextAttributeDeclIndex, fAttributeDeclNextAttributeDeclIndex.length * 2);
-        } catch (NullPointerException ex) {
-            // ignore
-        }
-        fAttributeDeclName[chunk] = new QName[CHUNK_SIZE];
-        fAttributeDeclType[chunk] = new int[CHUNK_SIZE];
-        fAttributeDeclEnumeration[chunk] = new int[CHUNK_SIZE];
-        fAttributeDeclDefaultType[chunk] = new int[CHUNK_SIZE];
-        fAttributeDeclDatatypeValidator[chunk] = new DatatypeValidator[CHUNK_SIZE];
-        fAttributeDeclDefaultValue[chunk] = new String[CHUNK_SIZE];
-        fAttributeDeclNextAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
-        return true;
-    }
-
-    // resize initial chunk
-
-    private int[][] resize(int array[][], int newsize) {
-        int newarray[][] = new int[newsize][];
-        System.arraycopy(array, 0, newarray, 0, array.length);
-        return newarray;
-    }
-
-    private DatatypeValidator[][] resize(DatatypeValidator array[][], int newsize) {
-        DatatypeValidator newarray[][] = new DatatypeValidator[newsize][];
-        System.arraycopy(array, 0, newarray, 0, array.length);
-        return newarray;
-    }
-
-    private XMLContentModel[][] resize(XMLContentModel array[][], int newsize) {
-        XMLContentModel newarray[][] = new XMLContentModel[newsize][];
-        System.arraycopy(array, 0, newarray, 0, array.length);
-        return newarray;
-    }
-
-    private QName[][] resize(QName array[][], int newsize) {
-        QName newarray[][] = new QName[newsize][];
-        System.arraycopy(array, 0, newarray, 0, array.length);
-        return newarray;
-    }
-
-    private String[][] resize(String array[][], int newsize) {
-        String newarray[][] = new String[newsize][];
-        System.arraycopy(array, 0, newarray, 0, array.length);
-        return newarray;
-    }
-
-    //
-    // Classes
-    //
-
-    /**
-     * Children list for <code>contentSpecTree</code> method.
-     */
-    static class ChildrenList {
-        public int length = 0;
-        public QName[] qname = new QName[2];
-        public int[] type = new int[2];
-    }
-
-} // class Grammar
diff --git a/src/org/apache/xerces/validators/common/GrammarResolver.java b/src/org/apache/xerces/validators/common/GrammarResolver.java
deleted file mode 100644
index 887562e..0000000
--- a/src/org/apache/xerces/validators/common/GrammarResolver.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-import java.util.*;
-import org.apache.xerces.validators.common.Grammar;
-
-/**
- * This class embodies the representation of a Grammar
- * pool Resolver.
- * This class is called from the validator.
- * 
- * 
- * @author Jeffrey Rodriguez
- */
-
-public interface GrammarResolver {
-    /**
-     * initializeGrammarRegistry - Gets call to register initial
-     * grammars such as DTD - Schema
-     */
-
-    /**
-     * 
-     * @param nameSpaceKey
-     *               Namespace key into Grammar pool
-     * @return                           Grammar abstraction associated
-     *         with NameSpace key.
-     */
-    public Grammar getGrammar( String nameSpaceKey );
-
-    /**
-     * 
-     * @return             Enumeration of String key name spaces in Grammar pool
-     */
-
-    public Enumeration nameSpaceKeys();
-
-    /**
-     * 
-     * @param nameSpaceKey
-     *                Key to associate with Grammar
-     *                abstraction
-     * @param grammar Grammar abstraction
-     *                used by validator.
-     */
-    public void putGrammar( String nameSpaceKey, Grammar grammar );
-
-    /**
-     * Removes association of Namespace key and Grammar from                         
-     * Grammar pool
-     * 
-     * @param nameSpaceKey
-     *               Name space key
-     */
-    public Grammar removeGrammar( String nameSpaceKey ); 
-
-
-
-    /**
-     *         Is Grammar abstraction in Grammar pool?
-     * 
-     * @param grammar Grammar Abstraction
-     * @return true  - Yes there is at least one instance
-     *         false - No
-     */
-    public boolean contains( Grammar grammar );
-
-    /**
-     *                Is Namespace key in Grammar pool
-     * 
-     * @param nameSpaceKey
-     *               Namespace key
-     * @return                Boolean- true - Namespace key association
-     *         is in grammar pool.
-     */
-    public boolean containsNameSpace( String nameSpaceKey ); 
-
-    /**
-     *         Reset internal Namespace/Grammar registry.
-     */
-    public void clearGrammarResolver();
-
-    /**
-     * 
-     * @return         Length of grammar pool. Number of associations.
-     */
-    public int size(); 
-
-}
-
-
-
diff --git a/src/org/apache/xerces/validators/common/GrammarResolverImpl.java b/src/org/apache/xerces/validators/common/GrammarResolverImpl.java
deleted file mode 100644
index 63134dc..0000000
--- a/src/org/apache/xerces/validators/common/GrammarResolverImpl.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-
-import java.util.*;
-import org.apache.xerces.validators.common.Grammar;
-import org.apache.xerces.validators.common.GrammarResolver;
-
-
-/**
- * This class embodies the representation of a Schema Grammar
- * pool.
- * This class is called from the validator.
- * Grammar pool maps to a set of Grammar Proxy classes.
- * 
- * @author Jeffrey Rodriguez
- * @version $Id$
- */
-public class GrammarResolverImpl implements GrammarResolver {
-
-    //
-    // Data
-    //
-
-    /**
-     *           Hashtable structure that represents a mapping
-     *           between Namespace and a Grammar
-     */
-    private Hashtable fGrammarRegistry    = new Hashtable();//This class keeps a hashtable of references to Grammar structures
-
-    //
-    // Constructors
-    //
-
-    /** Default constructor. */
-    public GrammarResolverImpl() {
-    }
-
-    //
-    // GrammarResolver methods
-    //
-
-    /**
-     * 
-     * @param nameSpaceKey
-     *               Namespace key into Grammar pool
-     * @return                           Grammar abstraction associated
-     *         with NameSpace key.
-     */
-    public Grammar getGrammar( String nameSpaceKey ) {
-        return(Grammar) ( fGrammarRegistry.get( nameSpaceKey ) ); 
-    }
-
-    /**
-     * 
-     * @return             Array of String key name spaces in Grammar pool
-     */
-    public String[] getNSKeysInPool() {
-        int numberOfNSKeysInPool = fGrammarRegistry.size();
-        String[] NSArray         = new String[numberOfNSKeysInPool];
-        Enumeration enumOfKeys   = nameSpaceKeys();
-        for (int i = 0; i<numberOfNSKeysInPool; i ++ ) {
-            NSArray[i] = (String )( enumOfKeys.nextElement() );
-        }
-        return NSArray;
-    }
-
-    /**
-     * 
-     * @param nameSpaceKey
-     *                Key to associate with Grammar
-     *                abstraction
-     * @param grammar Grammar abstraction
-     *                used by validator.
-     */
-    public void putGrammar( String nameSpaceKey, Grammar grammar ){
-        fGrammarRegistry.put( nameSpaceKey, grammar ); 
-    }
-
-    /**
-     * 
-     * @return         Length of grammar pool. Number of associations.
-     */
-    public int size() {
-        return fGrammarRegistry.size();
-    }
-
-     /**
-     * 
-     * @return             Enumeration of String key name spaces in Grammar pool
-     */
-
-    public Enumeration nameSpaceKeys(){
-        return fGrammarRegistry.keys();
-    }
-
-
-    /**
-     * Removes association of Namespace key and Grammar from                         
-     * Grammar pool
-     * 
-     * @param nameSpaceKey
-     *               Name space key
-     */
-    public Grammar removeGrammar( String nameSpaceKey ) {
-        if ( containsNameSpace( nameSpaceKey ) == true )
-          fGrammarRegistry.remove( nameSpaceKey );
-        return null;
-    }
-
-
-
-    /**
-     *         Is Grammar abstraction in Grammar pool?
-     * 
-     * @param grammar Grammar Abstraction
-     * @return true  - Yes there is at least one instance
-     *         false - No
-     */
-    public boolean contains( Grammar grammar ){
-        return fGrammarRegistry.contains( grammar );
-    }
-
-    /**
-     *                Is Namespace key in Grammar pool
-     * 
-     * @param nameSpaceKey
-     *               Namespace key
-     * @return                Boolean- true - Namespace key association
-     *         is in grammar pool.
-     */
-    public boolean containsNameSpace( String nameSpaceKey ){
-        return fGrammarRegistry.containsKey( nameSpaceKey );
-    }
-
-    /**
-     *         Reset internal Namespace/Grammar registry.
-     */
-    public void clearGrammarResolver() { 
-        fGrammarRegistry.clear();
-    }
-
-
-
-
-
-
-    /* Unit Test
-
-    static final int NGRAMMARS  = 10;
-
-
-    public static void main( String args[] ) 
-    {
-        //static final int NGRAMMARS  = 10;
-        SchemaGrammarResolver grammarPool     = SchemaGrammarResolver.instanceGrammarResolver();
-        Grammar     testGrammars[]  = new Grammar[NGRAMMARS]; 
-        String      testNameSpace[] = {
-        "http://www.foo1.org/",
-        "http://www.foo2.org/", 
-        "http://www.foo3.org/", 
-        "http://www.foo4.org/", 
-        "http://www.foo5.org/", 
-        "http://www.foo6.org/", 
-        "http://www.foo7.org/", 
-        "http://www.foo8.org/", 
-        "http://www.foo9.org/", 
-        "http://www.foox.org/" }; 
-
-        for( int  i = 0; i< NGRAMMARS ; i++ ) {
-        testGrammars[i] = new Grammar( testNameSpace[i] );
-        }
-
-
-        for( int i = 0; i<testGrammars.length; i++ ) {
-            grammarPool.addGrammar( testNameSpace[i], testGrammars[i] );
-        }
-        String [] localNames = grammarPool.getNSKeysInPool();
-        for( int i = 0; i<localNames.length; i++ ){
-            System.out.println( "Key[" + i + "] =" + localNames[i] );
-        }
-        // Get a couple of Grammars.
-
-        Grammar gramm1 = grammarPool.getGrammar( "http://www.foo2.org/" ); 
-        Grammar gramm2 = grammarPool.getGrammar( "http://www.foox.org/" );
-
-        System.out.println( "Grammar1 id = " + gramm1.whatGrammarAmI() + " It should be http://www.foo2.org/" );
-        System.out.println( "Grammar1 id = " + gramm2.whatGrammarAmI() + " It should be http://www.foox.org/" );
-         
-        Grammar myTestGrammar = new Grammar( "testgrammar" );
-        
-        boolean isInPool = grammarPool.isGrammarInPool( myTestGrammar);
-        System.out.println( "Grammar " + myTestGrammar.whatGrammarAmI()  + "Is in pool = " +  isInPool );
-        
-        grammarPool.addGrammar("myNSTest", myTestGrammar );
-        isInPool = grammarPool.isGrammarInPool( myTestGrammar);
-        System.out.println( "Just added Grammar " + myTestGrammar.whatGrammarAmI()  + "Is in pool = " +  isInPool );
-                    
-        String myNSTest = "http://www.foo.com/";
-        isInPool = grammarPool.isNSInPool(myNSTest);
-
-        System.out.println( "NS: " + myNSTest  + "Is in pool = " +  isInPool ); 
-        grammarPool.addGrammar(myNSTest, new Grammar( myNSTest ));
-        
-        isInPool = grammarPool.isNSInPool(myNSTest);
-
-        System.out.println( "NS: " + myNSTest  + "Is in pool = " +  isInPool ); 
-
-        System.out.println( "Length of Grammar pool = " + grammarPool.length() );
-               
-        grammarPool.resetGrammarPool();
-        System.out.println( "Length of Grammar pool now = " + grammarPool.length() );
-
-        grammarPool.addGrammar("myNSTest", myTestGrammar ); // The same key
-        grammarPool.addGrammar("myNSTest", myTestGrammar );
-        grammarPool.addGrammar("myNSTest", myTestGrammar );
-        grammarPool.addGrammar("myNSTest", myTestGrammar );
-        grammarPool.addGrammar("myNSTest", myTestGrammar );
-
-        System.out.println( "Length of Grammar pool now better not be 5 = " + grammarPool.length() );
-        for( int i = 0; i<testGrammars.length; i++ ) {
-        grammarPool.addGrammar( testNameSpace[i], testGrammars[i] );
-        }
-        grammarPool.deleteGrammarForNS( "myNSTest" );
-        System.out.println( "Length of Grammar pool now better not be 5 = " + grammarPool.length() );
-        localNames = grammarPool.getNSKeysInPool();
-        for( int i = 0; i<localNames.length; i++ ){
-                   System.out.println( "Key[" + i + "] =" + localNames[i] );
-           }
-    }
-    */
-
-} // class GrammarResolverImpl
diff --git a/src/org/apache/xerces/validators/common/InsertableElementsInfo.java b/src/org/apache/xerces/validators/common/InsertableElementsInfo.java
deleted file mode 100644
index 42414fa..0000000
--- a/src/org/apache/xerces/validators/common/InsertableElementsInfo.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.utils.QName;
-
-/**
- * ---------------------------------------------------------------------------
- *  InsertableElementsInfo is a simple 'data packet' class that is used to
- *  get information into and out of the validator APIs that allow you to ask
- *  what kind of elements can be inserted into a particular place in an
- *  element's content model.
- *
- *  The parent element is not explicitly stored here, since it is a separate
- *  parameter to the methods that do the query.
- *
- *  Since it exists purely to exchange data, it just uses simple public
- *  data members.
- * ---------------------------------------------------------------------------
- * InsertableElementsInfo is a simple 'data packet' class that is used to
- * get information into and out of the validator APIs that allow you to ask
- * what kind of elements can be inserted into a particular place in an
- * element's content model.
- * <p>
- * The parent element is not explicitly stored here, since it is a separate
- * parameter to the methods that do the query.
- * <p>
- * Since it exists purely to exchange data, it just uses simple public
- * data members.
- *
- * @version $Id$
- */
-public class InsertableElementsInfo
-{
-    /**
-     * One of the things that could be inserted here is a PCDATA node,
-     * in addition to the element type nodes reported.
-     */
-    public boolean canHoldPCData;
-
-    /**
-     * The count of elements in the curChildren array. The array can be
-     * larger than this (for reuse purposes), so this value indicates
-     * how many elements are valid.
-     * <p>
-     * Note that, since the curChildren array must have an empty slot at
-     * the insertion index, this value can never be zero.
-     * <p>
-     * Note also that this value can be changed during processing, though
-     * its value on return is meaningless to the caller.
-     */
-    public int childCount;
-    
-    /**
-     * The current list of children of the parent element. This may or
-     * may not be the <em>real</em> list of children, since the caller can lie
-     * but that's of no concern to the validator. These query APIs are
-     * intended to be for 'what if' kind of work, so any list of children
-     * could be passed in.
-     * <p>
-     * There must be an empy slot in the array at the requested insertion
-     * point. That slot does not have to have any particular value, but
-     * it will be used by the validator to do brute force validation in
-     * some cases when a 'fully valid' check is done for valid insertable
-     * elements.
-     * <p>
-     * Note that this array can be modified by the call, so do not expect
-     * its contents to remain the same as on input.
-     */
-    public QName curChildren[];
-
-    /**
-     * Indicates that one of the valid things after the insert point is
-     * 'end of content', which means that the element being inserted
-     * after can legally be the last element.
-     */
-    public boolean isValidEOC;
-    
-    /**
-     * The insertion point. The question is 'what can go here' and this
-     * indicates where 'where' is. It is an offset into curChildren.
-     */
-    public int insertAt;
-    
-    /**
-     * This array is filled with flags that indicate what the possible
-     * insertable elements are (i.e. the list of unique elements that
-     * could possibly be inserted somewhere in this type of element.)
-     * Effectively this is the list of unique children in the content
-     * model of the parent element.
-     * <p>
-     * If this array is not big enough to hold the results, or is null,
-     * then it will be replaced with a new array of the correct size.
-     */
-    public QName possibleChildren[];
-    
-    /**
-     * The number of elements that are valid in the possibleChildren
-     * and resultsCount arrays. They can be larger than that, so there
-     * must be a way to indicate how many elements are filled in with
-     * value results. If they were not at least this large on input,
-     * then they will be reallocated up to this size.
-     */
-    public int resultsCount;
-    
-    /**
-     * This array must be at least as large as possibleChildren since
-     * a flag is set in the same indexes in this array to indicate that
-     * the possible child at that index in possibleChildren can be
-     * inserted at the requested insertion point.
-     * <p>
-     * If this array is not big enough to hold the results, or is null,
-     * then it will be replaced with a new array of the correct size.
-     */
-    public boolean results[];
-    
-} // class InsertableElementsInfo
diff --git a/src/org/apache/xerces/validators/common/Makefile b/src/org/apache/xerces/validators/common/Makefile
deleted file mode 100644
index b90657c..0000000
--- a/src/org/apache/xerces/validators/common/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-TARGETS=\
-	CMAny.class\
-	CMBinOp.class\
-	CMException.class\
-	CMLeaf.class\
-	CMNode.class\
-	CMStateSet.class\
-	CMUniOp.class\
-	ContentLeafNameTypeVector.class\
-	DFAContentModel.class\
-	InsertableElementsInfo.class\
-	MixedContentModel.class\
-	SimpleContentModel.class\
-	XMLContentModel.class\
-	GrammarResolver.class \
-	GrammarResolverImpl.class \
-	Grammar.class \
-	XMLValidator.class
-
-
-
-DIRS =
-
-TOP = ../../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xerces/validators/common/MixedContentModel.java b/src/org/apache/xerces/validators/common/MixedContentModel.java
deleted file mode 100644
index 8306ef1..0000000
--- a/src/org/apache/xerces/validators/common/MixedContentModel.java
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.framework.XMLContentSpec;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.validators.schema.EquivClassComparator;
-
-/**
- * MixedContentModel is a derivative of the abstract content model base
- * class that handles the special case of mixed model elements. If an element
- * is mixed model, it has PCDATA as its first possible content, followed
- * by an alternation of the possible children. The children cannot have any
- * numeration or order, so it must look like this:
- * <pre>
- *   &lt;!ELEMENT Foo ((#PCDATA|a|b|c|)*)&gt;
- * </pre>
- * So, all we have to do is to keep an array of the possible children and
- * validate by just looking up each child being validated by looking it up
- * in the list.
- *
- * @version $Id$
- */
-public class MixedContentModel 
-    implements XMLContentModel {
-
-
-    //
-    // Data
-    //
-    
-    /** The count of possible children that we have to deal with. */
-    private int fCount;
-
-    /** The list of possible children that we have to accept. */
-    private QName fChildren[];
-
-    /** The type of the children to support ANY. */
-    private int fChildrenType[];
-
-    /* this is the EquivClassComparator object */
-    private EquivClassComparator comparator = null;
-    
-    /** 
-     * True if mixed content model is ordered. DTD mixed content models
-     * are <em>always</em> unordered.
-     */
-    private boolean fOrdered;
-
-    /** Boolean to allow DTDs to validate even with namespace support. */
-    private boolean fDTD;
-
-    //
-    // Constructors
-    //
-
-    /**
-     * Constructs a mixed content model.
-     *
-     * @param count The child count.
-     * @param childList The list of allowed children.
-     *
-     * @exception CMException Thrown if content model can't be built.
-     */
-    public MixedContentModel(QName childList[],
-                             int childListType[],
-                             int offset, int length) throws CMException {
-        this(childList, childListType, offset, length, false, false);
-    }
-
-    /**
-     * Constructs a mixed content model.
-     *
-     * @param count The child count.
-     * @param childList The list of allowed children.
-     * @param ordered True if content must be ordered.
-     *
-     * @exception CMException Thrown if content model can't be built.
-     */
-    public MixedContentModel(QName childList[],
-                             int childListType[],
-                             int offset, int length,
-                             boolean ordered) throws CMException {
-        this(childList, childListType, offset, length, ordered, false);
-    }
-
-    /**
-     * Constructs a mixed content model.
-     *
-     * @param count The child count.
-     * @param childList The list of allowed children.
-     * @param ordered True if content must be ordered.
-     *
-     * @exception CMException Thrown if content model can't be built.
-     */
-    public MixedContentModel(QName childList[],
-                             int childListType[],
-                             int offset, int length,
-                             boolean ordered,
-                             boolean dtd) throws CMException {
-
-        // Make our own copy now, which is exactly the right size
-        fCount = length;
-        fChildren = new QName[fCount];
-        fChildrenType = new int[fCount];
-        for (int i = 0; i < fCount; i++) {
-            fChildren[i] = new QName(childList[offset + i]);
-            fChildrenType[i] = childListType[offset + i];
-        }
-        fOrdered = ordered;
-
-        fDTD = dtd;
-
-    } // <init>(QName[],int[],int,int,boolean,boolean)
-    
-    //
-    // XMLContentModel methods
-    //
-    
-    /**
-     * Check that the specified content is valid according to this
-     * content model. This method can also be called to do 'what if' 
-     * testing of content models just to see if they would be valid.
-     * <p>
-     * A value of -1 in the children array indicates a PCDATA node. All other 
-     * indexes will be positive and represent child elements. The count can be
-     * zero, since some elements have the EMPTY content model and that must be 
-     * confirmed.
-     *
-     * @param children The children of this element.  Each integer is an index within
-     *                 the <code>StringPool</code> of the child element name.  An index
-     *                 of -1 is used to indicate an occurrence of non-whitespace character
-     *                 data.
-     * @param offset Offset into the array where the children starts.
-     * @param length The number of entries in the <code>children</code> array.
-     *
-     * @return The value -1 if fully valid, else the 0 based index of the child
-     *         that first failed. If the value returned is equal to the number
-     *         of children, then the specified children are valid but additional
-     *         content is required to reach a valid ending state.
-     *
-     * @exception Exception Thrown on error.
-     */
-    public int validateContent(QName children[], int offset, int length) 
-        throws Exception {
-        
-        // must match order
-        if (fOrdered) {
-            int inIndex = 0;
-            for (int outIndex = 0; outIndex < length; outIndex++) {
-
-                // ignore mixed text
-                final QName curChild = children[offset + outIndex];
-                if (curChild.localpart == -1) {
-                    continue;
-                }
-
-                // element must match
-                int type = fChildrenType[inIndex];
-                if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-                    if (fDTD) {
-                        if (fChildren[inIndex].rawname != children[offset + outIndex].rawname) {
-                            return outIndex;
-                        }
-                    }
-                    else {
-                        if (fChildren[inIndex].uri != children[offset + outIndex].uri &&
-                            fChildren[inIndex].localpart != children[offset + outIndex].localpart) {
-                            return outIndex;
-                        }
-                    }
-                }
-                else if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
-                    int uri = fChildren[inIndex].uri;
-                    if (uri != -1 && uri != children[outIndex].uri) {
-                        return outIndex;
-                    }
-                }
-                else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
-                    if (children[outIndex].uri != -1) {
-                        return outIndex;
-                    }
-                }
-                else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
-                    if (fChildren[inIndex].uri == children[outIndex].uri) {
-                        return outIndex;
-                    }
-                }
-                
-                // advance index
-                inIndex++;
-            }
-        }
-
-        // can appear in any order
-        else {
-            for (int outIndex = 0; outIndex < length; outIndex++)
-            {
-                // Get the current child out of the source index
-                final QName curChild = children[offset + outIndex];
-    
-                // If its PCDATA, then we just accept that
-                if (curChild.localpart == -1)
-                    continue;
-    
-                // And try to find it in our list
-                int inIndex = 0;
-                for (; inIndex < fCount; inIndex++)
-                {
-                    int type = fChildrenType[inIndex];
-                    if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-                        if (fDTD) {
-                            if (curChild.rawname == fChildren[inIndex].rawname) {
-                                break;
-                            }
-                        }
-                        else {
-                            if (curChild.uri == fChildren[inIndex].uri &&
-                                curChild.localpart == fChildren[inIndex].localpart)
-                                break;
-                        }
-                    }
-                    else if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
-                        int uri = fChildren[inIndex].uri;
-                        if (uri == -1 || uri == children[outIndex].uri) {
-                            break;
-                        }
-                    }
-                    else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
-                        if (children[outIndex].uri == -1) {
-                            break;
-                        }
-                    }
-                    else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
-                        if (fChildren[inIndex].uri != children[outIndex].uri) {
-                            break;
-                        }
-                    }
-                    // REVISIT: What about checking for multiple ANY matches?
-                    //          The content model ambiguity *could* be checked
-                    //          by the caller before constructing the mixed
-                    //          content model.
-                }
-
-                // We did not find this one, so the validation failed
-                if (inIndex == fCount)
-                    return outIndex;
-            }
-        }
-
-        // Everything seems to be in order, so return success
-        return -1;
-
-    }
-
-    public int validateContentSpecial(QName children[], int offset, int length) throws Exception{
-         //TO DO here. cause Mixed Content is only for DTD, Schema is kind of different.
-            return validateContent(children,offset, length);
-    }
-
-    public void setEquivClassComparator(EquivClassComparator comparator) {
-        this.comparator = comparator;
-    }
-
-    /**
-     * Returns information about which elements can be placed at a particular point
-     * in the passed element's content model.
-     * <p>
-     * Note that the incoming content model to test must be valid at least up to
-     * the insertion point. If not, then -1 will be returned and the info object
-     * will not have been filled in.
-     * <p>
-     * If, on return, the info.isValidEOC flag is set, then the 'insert after'
-     * element is a valid end of content. In other words, nothing needs to be
-     * inserted after it to make the parent element's content model valid.
-     *
-     * @param fullyValid Only return elements that can be inserted and still
-     *                   maintain the validity of subsequent elements past the
-     *                   insertion point (if any).  If the insertion point is at
-     *                   the end, and this is true, then only elements that can
-     *                   be legal final states will be returned.
-     * @param info An object that contains the required input data for the method,
-     *             and which will contain the output information if successful.
-     *
-     * @return The value -1 if fully valid, else the 0 based index of the child
-     *         that first failed before the insertion point. If the value 
-     *         returned is equal to the number of children, then the specified
-     *         children are valid but additional content is required to reach a
-     *         valid ending state.
-     *
-     * @see InsertableElementsInfo
-     */
-    public int whatCanGoHere(boolean                    fullyValid
-                            , InsertableElementsInfo    info) throws Exception
-    {
-        //
-        //  For this one, having the empty slot at the insertion point is 
-        //  a problem. So lets compress the array down. We know that it has
-        //  to have at least the empty slot at the insertion point.
-        //
-        for (int index = info.insertAt; index < info.childCount; index++)
-            info.curChildren[index] = info.curChildren[index+1];
-        info.childCount--;
-
-        //
-        //  Check the validity of the existing contents. If this is less than
-        //  the insert at point, then return failure index right now
-        //
-        final int failedIndex = validateContent(info.curChildren, 0, info.childCount);
-        if ((failedIndex != -1) && (failedIndex < info.insertAt))
-            return failedIndex;
-
-        //
-        //  Set any stuff we can know right off the bat for all cases. Mixed
-        //  models can always hold PCData. And, since its always a repetition
-        //  of a bunch of choice nodes, its always valid EOC.
-        //
-        info.canHoldPCData = true;
-        info.isValidEOC = true;
-
-        //
-        //  Set the results count member and then see if we need to reallocate
-        //  the outgoing arrays.
-        //
-        info.resultsCount = fCount;
-
-        if ((info.results == null) || (info.results.length < info.resultsCount))
-            info.results = new boolean[info.resultsCount];
-
-        if ((info.possibleChildren == null)
-        ||  (info.possibleChildren.length < info.resultsCount))
-        {
-            info.possibleChildren = new QName[info.resultsCount];
-            for (int i = 0; i < info.possibleChildren.length; i++) {
-                info.possibleChildren[i] = new QName();
-            }
-        }
-
-        //
-        //  If the fully valid parameter is set, then whether any child can
-        //  go here is dependent upon the content model having been valid all
-        //  the way to the end. If its not, nothing we put here is going to
-        //  make it happy. If it was ok, then nothing we put here is ever going
-        //  make it bad.
-        //
-        //  So set up a boolean that can be used to set every possible child's
-        //  insertable status below.
-        //
-        boolean bStatus = true;
-        if (fullyValid && (failedIndex < info.childCount))
-            bStatus = false;
-
-        //
-        //  Fill in the possible children array, from our array. And set the
-        //  boolean flag for each one to true because any of them can go
-        //  anywhere.
-        //
-        for (int index = 0; index < fCount; index++)
-        {
-            info.possibleChildren[index].setValues(fChildren[index]);
-            info.results[index] = bStatus;
-        }
-
-        return -1;
-    }
-
-
-    public ContentLeafNameTypeVector getContentLeafNameTypeVector() {
-        return null;
-    }
-
-
-} // class MixedContentModel
diff --git a/src/org/apache/xerces/validators/common/SimpleContentModel.java b/src/org/apache/xerces/validators/common/SimpleContentModel.java
deleted file mode 100644
index 4895c91..0000000
--- a/src/org/apache/xerces/validators/common/SimpleContentModel.java
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.framework.XMLContentSpec;
-import org.apache.xerces.utils.ImplementationMessages;
-import org.apache.xerces.utils.QName;
-
-import org.apache.xerces.validators.schema.EquivClassComparator;
-
-/**
- * SimpleContentModel is a derivative of the abstract content model base
- * class that handles a small set of simple content models that are just
- * way overkill to give the DFA treatment.
- * <p>
- * This class handles the following scenarios:
- * <ul>
- * <li> a
- * <li> a?
- * <li> a*
- * <li> a+
- * <li> a,b
- * <li> a|b
- * </ul>
- * <p>
- * These all involve a unary operation with one element type, or a binary
- * operation with two elements. These are very simple and can be checked
- * in a simple way without a DFA and without the overhead of setting up a
- * DFA for such a simple check.
- *
- * @version $Id$
- */
-public class SimpleContentModel 
-    implements XMLContentModel {
-
-    //
-    // Data
-    //
-
-    /**
-     * The element decl pool indices of the first (and optional second)
-     * child node. The operation code tells us whether the second child
-     * is used or not.
-     */
-    private QName fFirstChild = new QName();
-
-    /**
-     * The element decl pool indices of the first (and optional second)
-     * child node. The operation code tells us whether the second child
-     * is used or not.
-     */
-    private QName fSecondChild = new QName();
-
-    /**
-     * The operation that this object represents. Since this class only
-     * does simple contents, there is only ever a single operation
-     * involved (i.e. the children of the operation are always one or
-     * two leafs.) This is one of the XMLDTDParams.CONTENTSPECNODE_XXX values.
-     */
-    private int fOp;
-
-    /** Boolean to allow DTDs to validate even with namespace support. */
-    private boolean fDTD;
-
-    /* this is the EquivClassComparator object */
-    private EquivClassComparator comparator = null;
-    
-    //
-    // Constructors
-    //
-
-    /**
-     * Constructs a simple content model.
-     *
-     * @param firstChildIndex The first child index
-     * @parma secondChildIndex The second child index.
-     * @param cmOp The content model operator.
-     *
-     * @see XMLContentSpec
-     */
-    public SimpleContentModel(QName firstChild, QName secondChild, int cmOp) {
-        this(firstChild, secondChild, cmOp, false);
-    }
-
-    /**
-     * Constructs a simple content model.
-     *
-     * @param firstChildIndex The first child index
-     * @parma secondChildIndex The second child index.
-     * @param cmOp The content model operator.
-     *
-     * @see XMLContentSpec
-     */
-    public SimpleContentModel(QName firstChild, QName secondChild, 
-                              int cmOp, boolean dtd) {
-        //
-        //  Store away the children and operation. This is all we need to
-        //  do the content model check.
-        //
-        //  The operation is one of the ContentSpecNode.NODE_XXX values!
-        //
-        fFirstChild.setValues(firstChild);
-        if (secondChild != null) {
-            fSecondChild.setValues(secondChild);
-        }
-        else {
-            fSecondChild.clear();
-        }
-        fOp = cmOp;
-        fDTD = dtd;
-    }
-
-
-    //
-    // XMLContentModel methods
-    //
-    
-    /**
-     * Check that the specified content is valid according to this
-     * content model. This method can also be called to do 'what if' 
-     * testing of content models just to see if they would be valid.
-     * <p>
-     * A value of -1 in the children array indicates a PCDATA node. All other 
-     * indexes will be positive and represent child elements. The count can be
-     * zero, since some elements have the EMPTY content model and that must be 
-     * confirmed.
-     *
-     * @param children The children of this element.  Each integer is an index within
-     *                 the <code>StringPool</code> of the child element name.  An index
-     *                 of -1 is used to indicate an occurrence of non-whitespace character
-     *                 data.
-     * @param offset Offset into the array where the children starts.
-     * @param length The number of entries in the <code>children</code> array.
-     *
-     * @return The value -1 if fully valid, else the 0 based index of the child
-     *         that first failed. If the value returned is equal to the number
-     *         of children, then the specified children are valid but additional
-     *         content is required to reach a valid ending state.
-     *
-     * @exception Exception Thrown on error.
-     */
-    public int validateContent(QName children[], int offset, int length) throws Exception {
-
-        //
-        //  According to the type of operation, we do the correct type of
-        //  content check.
-        //
-        switch(fOp)
-        {
-            case XMLContentSpec.CONTENTSPECNODE_LEAF :
-                // If there is not a child, then report an error at index 0
-                if (length == 0)
-                    return 0;
-
-                // If the 0th child is not the right kind, report an error at 0
-                if (fDTD) {
-                    if (children[offset].rawname != fFirstChild.rawname) {
-                        return 0;
-                    }
-                }
-                else {
-                    if (children[offset].uri != fFirstChild.uri || 
-                        children[offset].localpart != fFirstChild.localpart)
-                        return 0;
-                }
-
-                // If more than one child, report an error at index 1
-                if (length > 1)
-                    return 1;
-                break;
-
-            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE :
-                //
-                //  If there is one child, make sure its the right type. If not,
-                //  then its an error at index 0.
-                //
-                if (length == 1) {
-                    if (fDTD) {
-                        if (children[offset].rawname != fFirstChild.rawname) {
-                            return 0;
-                        }
-                    }
-                    else {
-                        if (children[offset].uri != fFirstChild.uri || 
-                         children[offset].localpart != fFirstChild.localpart)
-                        return 0;
-                    }
-                }
-
-                //
-                //  If the child count is greater than one, then obviously
-                //  bad, so report an error at index 1.
-                //
-                if (length > 1)
-                    return 1;
-                break;
-
-            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE :
-                //
-                //  If the child count is zero, that's fine. If its more than
-                //  zero, then make sure that all children are of the element
-                //  type that we stored. If not, report the index of the first
-                //  failed one.
-                //
-                if (length > 0)
-                {
-                    if (fDTD) {
-                        for (int index = 0; index < length; index++) {
-                            if (children[offset + index].rawname != fFirstChild.rawname) {
-                                return index;
-                            }
-                        }
-                    }
-                    else {
-                        for (int index = 0; index < length; index++)
-                        {
-                            if (children[offset + index].uri != fFirstChild.uri || 
-                                children[offset + index].localpart != fFirstChild.localpart)
-                                return index;
-                        }
-                    }
-                }
-                break;
-
-            case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE :
-                //
-                //  If the child count is zero, that's an error so report
-                //  an error at index 0.
-                //
-                if (length == 0)
-                    return 0;
-
-                //
-                //  Otherwise we have to check them all to make sure that they
-                //  are of the correct child type. If not, then report the index
-                //  of the first one that is not.
-                //
-                if (fDTD) {
-                    for (int index = 0; index < length; index++) {
-                        if (children[offset + index].rawname != fFirstChild.rawname) {
-                            return index;
-                        }
-                    }
-                }
-                else {
-                    for (int index = 0; index < length; index++)
-                    {
-                        if (children[offset + index].uri != fFirstChild.uri || 
-                            children[offset + index].localpart != fFirstChild.localpart)
-                            return index;
-                    }
-                }
-                break;
-
-            case XMLContentSpec.CONTENTSPECNODE_CHOICE :
-                //
-                //  There must be one and only one child, so if the element count
-                //  is zero, return an error at index 0.
-                //
-                if (length == 0)
-                    return 0;
-
-                // If the zeroth element isn't one of our choices, error at 0
-                if (fDTD) {
-                    if ((children[offset].rawname != fFirstChild.rawname) &&
-                        (children[offset].rawname != fSecondChild.rawname)) {
-                        return 0;
-                    }
-                }
-                else {
-                    if ((children[offset].uri != fFirstChild.uri || children[offset].localpart != fFirstChild.localpart) &&
-                        (children[offset].uri != fSecondChild.uri || children[offset].localpart != fSecondChild.localpart))
-                        return 0;
-                }
-
-                // If there is more than one element, then an error at 1
-                if (length > 1)
-                    return 1;
-                break;
-
-            case XMLContentSpec.CONTENTSPECNODE_SEQ :
-                //
-                //  There must be two children and they must be the two values
-                //  we stored, in the stored order.
-                //
-                if (length == 2) {
-                    if (fDTD) {
-                        if (children[offset].rawname != fFirstChild.rawname) {
-                            return 0;
-                        }
-                        if (children[offset + 1].rawname != fSecondChild.rawname) {
-                            return 1;
-                        }
-                    }
-                    else {
-                        if (children[offset].uri != fFirstChild.uri || children[offset].localpart != fFirstChild.localpart)
-                            return 0;
-
-                        if (children[offset + 1].uri != fSecondChild.uri || children[offset + 1].localpart != fSecondChild.localpart)
-                            return 1;
-                    }
-                }
-                else {
-                    if (length > 2) {
-                        return 2;
-                    }
-
-                    return length;
-                }
-
-                break;
-
-            default :
-                throw new CMException(ImplementationMessages.VAL_CST);
-        }
-
-        // We survived, so return success status
-        return -1;
-    }
-    
-    public int validateContentSpecial(QName children[], int offset, int length) throws Exception{
-
-        if (comparator==null) {
-            return validateContent(children,offset, length);
-        }
-        //
-        //  According to the type of operation, we do the correct type of
-        //  content check.
-        //
-        switch(fOp)
-        {
-            case XMLContentSpec.CONTENTSPECNODE_LEAF :
-                // If there is not a child, then report an error at index 0
-                if (length == 0)
-                    return 0;
-
-                // If the 0th child is not the right kind, report an error at 0
-                if (children[offset].uri != fFirstChild.uri || 
-                    children[offset].localpart != fFirstChild.localpart)
-                    if (!comparator.isEquivalentTo(children[offset], fFirstChild)) 
-                        return 0;
-
-                // If more than one child, report an error at index 1
-                if (length > 1)
-                    return 1;
-                break;
-
-            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE :
-                //
-                //  If there is one child, make sure its the right type. If not,
-                //  then its an error at index 0.
-                //
-                if (length == 1 && 
-                    (children[offset].uri != fFirstChild.uri || 
-                     children[offset].localpart != fFirstChild.localpart))
-                    if (!comparator.isEquivalentTo(children[offset], fFirstChild)) 
-                        return 0;
-
-                //
-                //  If the child count is greater than one, then obviously
-                //  bad, so report an error at index 1.
-                //
-                if (length > 1)
-                    return 1;
-                break;
-
-            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE :
-                //
-                //  If the child count is zero, that's fine. If its more than
-                //  zero, then make sure that all children are of the element
-                //  type that we stored. If not, report the index of the first
-                //  failed one.
-                //
-                if (length > 0)
-                {
-                    for (int index = 0; index < length; index++)
-                    {
-                        if (children[offset + index].uri != fFirstChild.uri || 
-                            children[offset + index].localpart != fFirstChild.localpart)
-                            if (!comparator.isEquivalentTo(children[offset+index], fFirstChild)) 
-                                return index;
-                    }
-                }
-                break;
-
-            case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE :
-                //
-                //  If the child count is zero, that's an error so report
-                //  an error at index 0.
-                //
-                if (length == 0)
-                    return 0;
-
-                //
-                //  Otherwise we have to check them all to make sure that they
-                //  are of the correct child type. If not, then report the index
-                //  of the first one that is not.
-                //
-                for (int index = 0; index < length; index++)
-                {
-                    if (children[offset + index].uri != fFirstChild.uri || 
-                        children[offset + index].localpart != fFirstChild.localpart)
-                        if (!comparator.isEquivalentTo(children[offset+index], fFirstChild)) 
-                            return index;
-                }
-                break;
-
-            case XMLContentSpec.CONTENTSPECNODE_CHOICE :
-                //
-                //  There must be one and only one child, so if the element count
-                //  is zero, return an error at index 0.
-                //
-                if (length == 0)
-                    return 0;
-
-                // If the zeroth element isn't one of our choices, error at 0
-                if ((children[offset].uri != fFirstChild.uri || children[offset].localpart != fFirstChild.localpart) &&
-                    (children[offset].uri != fSecondChild.uri || children[offset].localpart != fSecondChild.localpart))
-                    if (   !comparator.isEquivalentTo(children[offset], fFirstChild) 
-                        && !comparator.isEquivalentTo(children[offset], fSecondChild) ) 
-                        return 0;
-
-                // If there is more than one element, then an error at 1
-                if (length > 1)
-                    return 1;
-                break;
-
-            case XMLContentSpec.CONTENTSPECNODE_SEQ :
-                //
-                //  There must be two children and they must be the two values
-                //  we stored, in the stored order.
-                //
-                if (length == 2) {
-                    if (children[offset].uri != fFirstChild.uri || children[offset].localpart != fFirstChild.localpart)
-                        if (!comparator.isEquivalentTo(children[offset], fFirstChild)) 
-                            return 0;
-
-                    if (children[offset + 1].uri != fSecondChild.uri || children[offset + 1].localpart != fSecondChild.localpart)
-                        if (!comparator.isEquivalentTo(children[offset+1], fSecondChild)) 
-                            return 1;
-                }
-                else {
-                    if (length > 2) {
-                        return 2;
-                    }
-
-                    return length;
-                }
-
-                break;
-
-            default :
-                throw new CMException(ImplementationMessages.VAL_CST);
-        }
-
-        // We survived, so return success status
-        return -1;
-    }
-
-    public void setEquivClassComparator(EquivClassComparator comparator) {
-        this.comparator = comparator;
-    }
-
-    /**
-     * Returns information about which elements can be placed at a particular point
-     * in the passed element's content model.
-     * <p>
-     * Note that the incoming content model to test must be valid at least up to
-     * the insertion point. If not, then -1 will be returned and the info object
-     * will not have been filled in.
-     * <p>
-     * If, on return, the info.isValidEOC flag is set, then the 'insert after'
-     * element is a valid end of content. In other words, nothing needs to be
-     * inserted after it to make the parent element's content model valid.
-     *
-     * @param fullyValid Only return elements that can be inserted and still
-     *                   maintain the validity of subsequent elements past the
-     *                   insertion point (if any).  If the insertion point is at
-     *                   the end, and this is true, then only elements that can
-     *                   be legal final states will be returned.
-     * @param info An object that contains the required input data for the method,
-     *             and which will contain the output information if successful.
-     *
-     * @return The value -1 if fully valid, else the 0 based index of the child
-     *         that first failed before the insertion point. If the value 
-     *         returned is equal to the number of children, then the specified
-     *         children are valid but additional content is required to reach a
-     *         valid ending state.
-     *
-     * @see InsertableElementsInfo
-     */
-    public int whatCanGoHere(boolean fullyValid, InsertableElementsInfo info) 
-        throws Exception {
-
-        //
-        //  For this one, having the empty slot at the insertion point is 
-        //  a problem. So lets compress the array down. We know that it has
-        //  to have at least the empty slot at the insertion point.
-        //
-        for (int index = info.insertAt; index < info.childCount; index++) {
-            info.curChildren[index].setValues(info.curChildren[index+1]);
-        }
-        info.childCount--;
-        
-        //
-        //  Check the validity of the existing contents. If this is less than
-        //  the insert at point, then return failure index right now
-        //
-        final int failedIndex = validateContent(info.curChildren, 0, info.childCount);
-        if ((failedIndex != -1) && (failedIndex < info.insertAt))
-            return failedIndex;
-
-        // Set any stuff we can know right off the bat for all cases
-        info.canHoldPCData = false;
-
-        // See how many children we can possibly report
-        if ((fOp == XMLContentSpec.CONTENTSPECNODE_LEAF)
-        ||  (fOp == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE)
-        ||  (fOp == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
-        ||  (fOp == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE))
-        {
-            info.resultsCount = 1;
-        }
-         else if ((fOp == XMLContentSpec.CONTENTSPECNODE_CHOICE)
-              ||  (fOp == XMLContentSpec.CONTENTSPECNODE_SEQ))
-        {
-            info.resultsCount = 2;
-        }
-         else
-        {
-            throw new CMException(ImplementationMessages.VAL_CST);
-        }
-
-        //
-        //  If the outgoing arrays are too small or null, create new ones. These
-        //  have to be at least the size of the results count.
-        //
-        if ((info.results == null) || (info.results.length < info.resultsCount))
-            info.results = new boolean[info.resultsCount];
-
-        if ((info.possibleChildren == null)
-        ||  (info.possibleChildren.length < info.resultsCount))
-        {
-            info.possibleChildren = new QName[info.resultsCount];
-            for (int i = 0; i < info.possibleChildren.length; i++) {
-                info.possibleChildren[i] = new QName();
-            }
-        }
-
-        //
-        //  Fill in the possible children array, and set all of the associated
-        //  results entries to defaults of false.
-        //
-        info.possibleChildren[0].setValues(fFirstChild);
-        info.results[0] = false;
-        if (info.resultsCount == 2)
-        {
-            info.possibleChildren[1].setValues(fSecondChild);
-            info.results[1] = false;
-        }
-
-        //
-        //  Set some defaults so that it does not have to be done redundantly
-        //  below in each case.
-        //
-        info.isValidEOC = false;
-
-        //
-        //  Now, for each spec type, lets do the grunt work required. Each of
-        //  them is pretty simple, its just making sure of corner cases.
-        //
-        //  We know its valid up to the insert point at least and we know that
-        //  the insert point is never past the number of children, so this releaves
-        //  a lot of checking below.
-        //
-        switch(fOp)
-        {
-            case XMLContentSpec.CONTENTSPECNODE_LEAF :
-            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE :
-                //
-                //  If there are no current children, then insert at has to be
-                //  zero, so we can have the one leaf element inserted here.
-                //
-                if (info.childCount == 0)
-                {
-                    info.results[0] = true;
-                }
-                 else if (info.childCount > 0)
-                {
-                    //
-                    //  If the child count is greater than zero, then inserting
-                    //  anything cannot be fully valid. But, if not fully valid
-                    //  checking, it is ok as long as inserting at zero.
-                    //
-                    if (!fullyValid && (info.insertAt == 0))
-                        info.results[0] = true;
-                }
-
-                if (fOp == XMLContentSpec.CONTENTSPECNODE_LEAF)
-                {
-                    // If the insert point is 1, then EOC is valid there
-                    if (info.insertAt == 0)
-                        info.isValidEOC = true;
-                }
-                 else
-                {
-                    // Its zero or one, so EOC is valid in either case
-                    info.isValidEOC = true;
-                }
-                break;
-
-            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE :
-            case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE :
-                //
-                //  The one child is always possible to insert, regardless of
-                //  where. The fully valid flag never comes into play since it
-                //  cannot become invalid by inserting any number of new
-                //  instances of the one element.
-                //
-                info.results[0] = true;
-
-                //
-                //  Its zero/one or more, so EOC is valid in either case but only
-                //  after the 0th index for one or more.
-                //
-                if ((fOp == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
-                ||  (info.insertAt > 0))
-                {
-                    info.isValidEOC = true;
-                }
-                break;
-
-            case XMLContentSpec.CONTENTSPECNODE_CHOICE :
-                //
-                //  If the insert point is zero, then either of the two children
-                //  can be inserted, unless fully valid is set and there are
-                //  already any children.
-                //
-                if (info.insertAt == 0)
-                {
-                    if (!fullyValid && (info.childCount == 0))
-                    {
-                        info.results[0] = true;
-                        info.results[1] = true;
-                    }
-                }
-
-                // EOC is only valid at the end
-                if (info.insertAt == 1)
-                    info.isValidEOC = true;
-                break;
-
-            case XMLContentSpec.CONTENTSPECNODE_SEQ :
-                //
-                //  If the insert at is 0, then the first one valid. Else its
-                //  the second one.
-                //
-                if (info.insertAt == 0)
-                {
-                    //
-                    //  If fully valid check, then if there are two children,
-                    //  it cannot be valid. If there is one child, it must be
-                    //  equal to the second child of the pattern since it will
-                    //  get pushed up (which means it was a pattern like (x|x)
-                    //  which is kinda wierd.)
-                    //
-                    if (fullyValid)
-                    {
-                        if (info.childCount == 1)
-                            info.results[0] = info.curChildren[0].uri == fSecondChild.uri &&
-                                              info.curChildren[0].localpart == fSecondChild.localpart;
-                    }
-                     else
-                    {
-                        info.results[0] = true;
-                    }
-                }
-                 else if (info.insertAt == 1)
-                {
-                    // If fully valid, then there cannot be two existing children
-                    if (!fullyValid || (info.childCount == 1))
-                        info.results[1] = true;
-                }
-
-                // EOC is only valid at the end
-                if (info.insertAt == 2)
-                    info.isValidEOC = true;
-                break;
-
-            default :
-                throw new CMException(ImplementationMessages.VAL_CST);
-        }
-
-        // We survived, so return success status
-        return -1;
-    }
-
-    public ContentLeafNameTypeVector getContentLeafNameTypeVector() {
-          return null;
-    }
-} // class SimpleContentModel
diff --git a/src/org/apache/xerces/validators/common/XMLAttributeDecl.java b/src/org/apache/xerces/validators/common/XMLAttributeDecl.java
deleted file mode 100644
index 6988734..0000000
--- a/src/org/apache/xerces/validators/common/XMLAttributeDecl.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.validators.datatype.DatatypeValidator;
-
-/**
- * @version $Id$
- */
-public class XMLAttributeDecl {
-
-    //
-    // Constants
-    //
-
-    // dtd
-
-    public static final int TYPE_CDATA = 0;
-    public static final int TYPE_ENTITY = 1;
-    public static final int TYPE_ENUMERATION = 2;
-    public static final int TYPE_ID = 3;
-    public static final int TYPE_IDREF = 4;
-    public static final int TYPE_NMTOKEN = 5;
-    public static final int TYPE_NOTATION = 6;
-
-    // schema
-
-    public static final int TYPE_SIMPLE = 7;
-
-    public static final int TYPE_ANY_ANY = 8;
-    public static final int TYPE_ANY_OTHER = 9;
-    public static final int TYPE_ANY_LOCAL = 10;
-    public static final int TYPE_ANY_LIST = 11;
-
-    // default type
-
-    public static final int DEFAULT_TYPE_IMPLIED = 0;
-    public static final int DEFAULT_TYPE_FIXED = 1;
-    public static final int DEFAULT_TYPE_REQUIRED = 2;
-    public static final int DEFAULT_TYPE_DEFAULT = 3;
-
-    // schema: attribte wildcard processContents property, share the defaultType field
-    public static final int PROCESSCONTENTS_STRICT = 4;
-    public static final int PROCESSCONTENTS_LAX = 5;
-    public static final int PROCESSCONTENTS_SKIP = 6;
-
-
-    //
-    // Data
-    //
-
-    // basic information
-
-    public QName name = new QName();
-
-    // simple types
-
-    public DatatypeValidator datatypeValidator;
-
-    // Att types, e.g. ID, IDREF, NOTATION, NMTOKEN, 
-
-    public int type;
-
-    public boolean list;
-
-    // values
-    public int enumeration;
-
-    public int defaultType;
-
-    public String defaultValue;
-
-    //
-    // Constructors
-    //
-
-    public XMLAttributeDecl() {
-        clear();
-    }
-
-    public XMLAttributeDecl(XMLAttributeDecl attributeDecl) {
-        setValues(attributeDecl);
-    }
-
-    //
-    // Public methods
-    //
-
-    public void clear() {
-        name.clear();
-        datatypeValidator = null;
-        type = -1;
-        list = false;
-        enumeration = -1;
-        defaultType = DEFAULT_TYPE_IMPLIED;
-        defaultValue = null;
-    }
-
-    public void setValues(XMLAttributeDecl attributeDecl) {
-        name.setValues(attributeDecl.name);
-        datatypeValidator = attributeDecl.datatypeValidator;
-        type = attributeDecl.type;
-        list = attributeDecl.list;
-        enumeration = attributeDecl.enumeration;
-        defaultType = attributeDecl.defaultType;
-        defaultValue = attributeDecl.defaultValue;
-    }
-
-    //
-    // Object methods
-    //
-
-    public int hashCode() {
-        // TODO
-        return super.hashCode();
-    }
-
-    public boolean equals(Object object) {
-        // TODO
-        return super.equals(object);
-    }
-
-} // class XMLAttributeDecl
diff --git a/src/org/apache/xerces/validators/common/XMLContentModel.java b/src/org/apache/xerces/validators/common/XMLContentModel.java
deleted file mode 100644
index 103a7aa..0000000
--- a/src/org/apache/xerces/validators/common/XMLContentModel.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.validators.schema.EquivClassComparator;
-
-/**
- * ContentModel is an interface that can be used by your own custom validators
- * to plug in various types of content models. It is used internally as well
- * for the same purposes.
- * <p>
- * Since there are a number of optimizations that can be used for simple or
- * special content models, this class provides the interface via which all of
- * the various content model types are managed. So the validation handler
- * class has a list of things derived from this class. It finds the one for
- * the desired element, then asks it to validate the element contents.
- * <p>
- * The validation interface from the scanner to the validation handle provides
- * a child count and an array of element name indices into the string pool.
- * So it is assumed that those same parameters will be passed to the content
- * model to be validated. Therefore the validateContent() method accepts
- * this standard view of the elements to be validated.
- *
- * @author  Dean Roddey, Eric Ye
- * @version $Id$
- */
-public interface XMLContentModel {
-
-    /**
-     * Check that the specified content is valid according to this
-     * content model. This method can also be called to do 'what if' 
-     * testing of content models just to see if they would be valid.
-     * <p>
-     * A value of -1 in the children array indicates a PCDATA node. All other 
-     * indexes will be positive and represent child elements. The count can be
-     * zero, since some elements have the EMPTY content model and that must be 
-     * confirmed.
-     *
-     * @param children The children of this element.  Each integer is an index within
-     *                 the <code>StringPool</code> of the child element name.  An index
-     *                 of -1 is used to indicate an occurrence of non-whitespace character
-     *                 data.
-     * @param offset Offset into the array where the children starts.
-     * @param length The number of entries in the <code>children</code> array.
-     *
-     * @return The value -1 if fully valid, else the 0 based index of the child
-     *         that first failed. If the value returned is equal to the number
-     *         of children, then the specified children are valid but additional
-     *         content is required to reach a valid ending state.
-     *
-     * @exception Exception Thrown on error.
-     */
-    public int validateContent(QName children[], int offset, int length) throws Exception;
-
-    /**
-     * This method is different from "validateContent" in that it will try to use
-     * the EquivClassComparator to match children against the content model.
-     * <p>
-     * A value of -1 in the children array indicates a PCDATA node. All other 
-     * indexes will be positive and represent child elements. The count can be
-     * zero, since some elements have the EMPTY content model and that must be 
-     * confirmed.
-     *
-     * @param children The children of this element.  Each integer is an index within
-     *                 the <code>StringPool</code> of the child element name.  An index
-     *                 of -1 is used to indicate an occurrence of non-whitespace character
-     *                 data.
-     * @param offset Offset into the array where the children starts.
-     * @param length The number of entries in the <code>children</code> array.
-     *
-     * @return The value -1 if fully valid, else the 0 based index of the child
-     *         that first failed. If the value returned is equal to the number
-     *         of children, then the specified children are valid but additional
-     *         content is required to reach a valid ending state.
-     *
-     * @exception Exception Thrown on error.
-     */
-    public int validateContentSpecial(QName children[], int offset, int length) throws Exception;
-
-    /**
-     * The setter method to pass in the EquivCLassComparator.
-     *
-     * @param comparator a EquivClassComparator object.
-     * @return 
-     * @exception 
-     */
-    public void setEquivClassComparator(EquivClassComparator comparator);// should really use a Comparator interface
-
-    /**
-     * Returns information about which elements can be placed at a particular point
-     * in the passed element's content model.
-     * <p>
-     * Note that the incoming content model to test must be valid at least up to
-     * the insertion point. If not, then -1 will be returned and the info object
-     * will not have been filled in.
-     * <p>
-     * If, on return, the info.isValidEOC flag is set, then the 'insert after'
-     * element is a valid end of content. In other words, nothing needs to be
-     * inserted after it to make the parent element's content model valid.
-     *
-     * @param fullyValid Only return elements that can be inserted and still
-     *                   maintain the validity of subsequent elements past the
-     *                   insertion point (if any).  If the insertion point is at
-     *                   the end, and this is true, then only elements that can
-     *                   be legal final states will be returned.
-     * @param info An object that contains the required input data for the method,
-     *             and which will contain the output information if successful.
-     *
-     * @return The value -1 if fully valid, else the 0 based index of the child
-     *         that first failed before the insertion point. If the value 
-     *         returned is equal to the number of children, then the specified
-     *         children are valid but additional content is required to reach a
-     *         valid ending state.
-     *
-     * @see InsertableElementsInfo
-     */
-    public int whatCanGoHere(boolean fullyValid, 
-                             InsertableElementsInfo info) throws Exception;
-
-    public ContentLeafNameTypeVector getContentLeafNameTypeVector() ;
-
-
-} // interface XMLContentModel
diff --git a/src/org/apache/xerces/validators/common/XMLElementDecl.java b/src/org/apache/xerces/validators/common/XMLElementDecl.java
deleted file mode 100644
index e7c0811..0000000
--- a/src/org/apache/xerces/validators/common/XMLElementDecl.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.validators.datatype.DatatypeValidator;
-
-/**
- * @version $Id$
- */
-public class XMLElementDecl {
-
-    //
-    // Constants
-    //
-
-    public static final int TYPE_EMPTY = 0;
-    public static final int TYPE_ANY = 1;
-    public static final int TYPE_MIXED = 2;
-    public static final int TYPE_CHILDREN = 3;
-    public static final int TYPE_SIMPLE = 4;
-
-    //
-    // Data
-    //
-
-    // basic information
-
-    public final QName name = new QName();
-
-    public int type;
-
-    // simple types
-
-    public boolean list;
-
-    public DatatypeValidator datatypeValidator;
-
-    // complex types
-
-    public int contentSpecIndex;
-
-    // enclosingScope where this element is declared, should always be -1 with DTD Validation.
-    public int enclosingScope;
-
-    //
-    // Constructors
-    //
-
-    public XMLElementDecl() {
-        clear();
-    }
-
-    public XMLElementDecl(XMLElementDecl elementDecl) {
-        setValues(elementDecl);
-    }
-
-    //
-    // Public methods
-    //
-
-    public void clear() {
-        name.clear();
-        type = - 1;
-        list = false;
-        datatypeValidator = null;
-        contentSpecIndex = -1;
-        enclosingScope = -1;
-    }
-
-    public void setValues(XMLElementDecl elementDecl) {
-        name.setValues(elementDecl.name);
-        type = elementDecl.type;
-        list = elementDecl.list;
-        datatypeValidator = elementDecl.datatypeValidator;
-        contentSpecIndex = elementDecl.contentSpecIndex;
-        enclosingScope = elementDecl.enclosingScope;
-    }
-
-    //
-    // Object methods
-    //
-
-    public int hashCode() {
-        // TODO
-        return super.hashCode();
-    }
-
-    public boolean equals(Object object) {
-        // TODO
-        return super.equals(object);
-    }
-
-} // class XMLElementDecl
diff --git a/src/org/apache/xerces/validators/common/XMLValidator.java b/src/org/apache/xerces/validators/common/XMLValidator.java
deleted file mode 100644
index 5a69574..0000000
--- a/src/org/apache/xerces/validators/common/XMLValidator.java
+++ /dev/null
@@ -1,3515 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.common;
-
-import org.apache.xerces.framework.XMLAttrList;
-import org.apache.xerces.framework.XMLContentSpec;
-import org.apache.xerces.framework.XMLDocumentHandler;
-import org.apache.xerces.framework.XMLDocumentScanner;
-import org.apache.xerces.framework.XMLErrorReporter;
-import org.apache.xerces.readers.DefaultEntityHandler;
-import org.apache.xerces.readers.XMLEntityHandler;
-import org.apache.xerces.utils.ChunkyCharArray;
-import org.apache.xerces.utils.Hash2intTable;
-import org.apache.xerces.utils.NamespacesScope;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.utils.XMLCharacterProperties;
-import org.apache.xerces.utils.XMLMessages;
-import org.apache.xerces.utils.ImplementationMessages;
-
-import org.apache.xerces.parsers.DOMParser;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import org.xml.sax.InputSource;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.Locator;
-import org.xml.sax.helpers.LocatorImpl;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-import java.io.IOException;
-
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.StringTokenizer;
-import java.util.Vector;
-
-import org.apache.xerces.validators.dtd.DTDGrammar;
-
-import org.apache.xerces.validators.schema.EquivClassComparator;
-import org.apache.xerces.validators.schema.SchemaGrammar;
-import org.apache.xerces.validators.schema.SchemaMessageProvider;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-import org.apache.xerces.validators.schema.TraverseSchema;
-
-import org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
-import org.apache.xerces.validators.datatype.DatatypeValidator;
-import org.apache.xerces.validators.datatype.InvalidDatatypeValueException;
-import org.apache.xerces.validators.datatype.StateMessageDatatype;
-import org.apache.xerces.validators.datatype.IDREFDatatypeValidator;
-import org.apache.xerces.validators.datatype.IDDatatypeValidator;
-import org.apache.xerces.validators.datatype.ENTITYDatatypeValidator;
-
-/**
- * This class is the super all-in-one validator used by the parser.
- *
- * @version $Id$
- */
-public final class XMLValidator
-implements DefaultEntityHandler.EventHandler,
-XMLEntityHandler.CharDataHandler,
-XMLDocumentScanner.EventHandler,
-NamespacesScope.NamespacesHandler {
-
-    //
-    // Constants
-    //
-
-    // debugging
-
-    private static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
-    private static final boolean DEBUG_PRINT_ATTRIBUTES = false;
-    private static final boolean DEBUG_PRINT_CONTENT = false;
-    private static final boolean DEBUG_SCHEMA_VALIDATION = false;
-    private static final boolean DEBUG_ELEMENT_CHILDREN = false;
-
-    // Chunk size constants
-
-    private static final int CHUNK_SHIFT = 8;           // 2^8 = 256
-    private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
-    private static final int CHUNK_MASK = CHUNK_SIZE - 1;
-    private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT));   // 2^10 = 1k
-
-    private Hashtable fIdDefs = null;
-
-
-    private  StateMessageDatatype fStoreIDRef = new StateMessageDatatype() {
-        private Hashtable fIdDefs;
-        public Object getDatatypeObject(){
-            return(Object) fIdDefs;
-        }
-        public int    getDatatypeState(){
-            return IDREFDatatypeValidator.IDREF_STORE;
-        }
-        public void setDatatypeObject( Object data ){
-            fIdDefs = (Hashtable) data;
-        }
-    };
-
-    private StateMessageDatatype fResetID = new StateMessageDatatype() {
-        public Object getDatatypeObject(){
-            return(Object) null;
-        }
-        public int    getDatatypeState(){
-            return IDDatatypeValidator.ID_CLEAR;
-        }
-        public void setDatatypeObject( Object data ){
-        }
-    };
-
-
-    private StateMessageDatatype fResetIDRef = new StateMessageDatatype() {
-        public Object getDatatypeObject(){
-            return(Object) null;
-        }
-        public int    getDatatypeState(){
-            return IDREFDatatypeValidator.IDREF_CLEAR;
-        }
-        public void setDatatypeObject( Object data ){
-        }
-    };
-
-    private  StateMessageDatatype fValidateIDRef = new StateMessageDatatype() {
-        public Object getDatatypeObject(){
-            return(Object) null;
-        }
-        public int    getDatatypeState(){
-            return IDREFDatatypeValidator.IDREF_VALIDATE;
-        }
-        public void setDatatypeObject( Object data ){
-        }
-    };
-
-
-    private  StateMessageDatatype fValidateENTITYMsg = new StateMessageDatatype() {
-        private  Object  packagedMessage = null;
-        public Object getDatatypeObject(){
-            return packagedMessage;
-        }
-        public int    getDatatypeState(){
-            return ENTITYDatatypeValidator.ENTITY_INITIALIZE;//No state
-        }
-        public void setDatatypeObject( Object data ){
-            packagedMessage = data;// Set Entity Handler
-        }
-    };
-
-    /*
-    private  StateMessageDatatype fValidateNOTATIONMsg = new StateMessageDatatype() {
-        private  Object  packagedMessage = null;
-        public Object getDatatypeObject(){
-            return packagedMessage;
-        }
-        public int    getDatatypeState(){
-            return NOTATIONDatatypeValidator.ENTITY_INITIALIZE;//No state
-        }
-        public void setDatatypeObject( Object data ){
-            packagedMessage = data;// Set Entity Handler
-        }
-    };
-    */
-
-
-
-
-
-    //
-    // Data
-    //
-
-    // REVISIT: The data should be regrouped and re-organized so that
-    //          it's easier to find a meaningful field.
-
-    // debugging
-
-//    private static boolean DEBUG = false;
-
-    // other
-
-    // attribute validators
-
-    private AttributeValidator fAttValidatorNOTATION = new AttValidatorNOTATION();
-    private AttributeValidator fAttValidatorENUMERATION = new AttValidatorENUMERATION();
-    private AttributeValidator fAttValidatorDATATYPE = null;
-
-    // Package access for use by AttributeValidator classes.
-
-    StringPool fStringPool = null;
-    boolean fValidating = false;
-    boolean fInElementContent = false;
-    int fStandaloneReader = -1;
-
-
-    // settings
-
-    private boolean fValidationEnabled = false;
-    private boolean fDynamicValidation = false;
-    private boolean fSchemaValidation = true;
-    private boolean fValidationEnabledByDynamic = false;
-    private boolean fDynamicDisabledByValidation = false;
-    private boolean fWarningOnDuplicateAttDef = false;
-    private boolean fWarningOnUndeclaredElements = false;
-    private boolean fLoadDTDGrammar = true;
-
-    // declarations
-
-    private int fDeclaration[];
-    private XMLErrorReporter fErrorReporter = null;
-    private DefaultEntityHandler fEntityHandler = null;
-    private QName fCurrentElement = new QName();
-
-    private ContentLeafNameTypeVector[] fContentLeafStack = new ContentLeafNameTypeVector[8];
-    private int[] fValidationFlagStack = new int[8];
-
-    private int[] fScopeStack = new int[8];
-    private int[] fGrammarNameSpaceIndexStack = new int[8];
-
-    private int[] fElementEntityStack = new int[8];
-    private int[] fElementIndexStack = new int[8];
-    private int[] fContentSpecTypeStack = new int[8];
-
-    private static final int sizeQNameParts      = 8;
-    private QName[] fElementQNamePartsStack      = new QName[sizeQNameParts];
-
-    private QName[] fElementChildren = new QName[32];
-    private int fElementChildrenLength = 0;
-    private int[] fElementChildrenOffsetStack = new int[32];
-    private int fElementDepth = -1;
-
-    private boolean fNamespacesEnabled = false;
-    private NamespacesScope fNamespacesScope = null;
-    private int fNamespacesPrefix = -1;
-    private QName fRootElement = new QName();
-    private int fAttrListHandle = -1;
-    private int fCurrentElementEntity = -1;
-    private int fCurrentElementIndex = -1;
-    private int fCurrentContentSpecType = -1;
-    private boolean fSeenDoctypeDecl = false;
-
-    private final int TOP_LEVEL_SCOPE = -1;
-    private int fCurrentScope = TOP_LEVEL_SCOPE;
-    private int fCurrentSchemaURI = -1;
-    private int fEmptyURI = - 1; 
-    private int fXsiPrefix = - 1;
-    private int fXsiURI = -2; 
-    private int fXsiTypeAttValue = -1;
-    private DatatypeValidator fXsiTypeValidator = null;
-
-    private Grammar fGrammar = null;
-    private int fGrammarNameSpaceIndex = -1;
-    private GrammarResolver fGrammarResolver = null;
-
-    // state and stuff
-
-    private boolean fScanningDTD = false;
-    private XMLDocumentScanner fDocumentScanner = null;
-    private boolean fCalledStartDocument = false;
-    private XMLDocumentHandler fDocumentHandler = null;
-    private XMLDocumentHandler.DTDHandler fDTDHandler = null;
-    private boolean fSeenRootElement = false;
-    private XMLAttrList fAttrList = null;
-    private int fXMLLang = -1;
-    private LocatorImpl fAttrNameLocator = null;
-    private boolean fCheckedForSchema = false;
-    private boolean fDeclsAreExternal = false;
-    private StringPool.CharArrayRange fCurrentElementCharArrayRange = null;
-    private char[] fCharRefData = null;
-    private boolean fSendCharDataAsCharArray = false;
-    private boolean fBufferDatatype = false;
-    private StringBuffer fDatatypeBuffer = new StringBuffer();
-
-    private QName fTempQName = new QName();
-    private XMLAttributeDecl fTempAttDecl = new XMLAttributeDecl();
-    private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
-    private XMLElementDecl fTempElementDecl = new XMLElementDecl();
-
-    private boolean fGrammarIsDTDGrammar = false;
-    private boolean fGrammarIsSchemaGrammar = false;
-
-    private boolean fNeedValidationOff = false;
-
-    // symbols
-
-    private int fEMPTYSymbol = -1;
-    private int fANYSymbol = -1;
-    private int fMIXEDSymbol = -1;
-    private int fCHILDRENSymbol = -1;
-    private int fCDATASymbol = -1;
-    private int fIDSymbol = -1;
-    private int fIDREFSymbol = -1;
-    private int fIDREFSSymbol = -1;
-    private int fENTITYSymbol = -1;
-    private int fENTITIESSymbol = -1;
-    private int fNMTOKENSymbol = -1;
-    private int fNMTOKENSSymbol = -1;
-    private int fNOTATIONSymbol = -1;
-    private int fENUMERATIONSymbol = -1;
-    private int fREQUIREDSymbol = -1;
-    private int fFIXEDSymbol = -1;
-    private int fDATATYPESymbol = -1;
-    private int fEpsilonIndex = -1;
-
-
-    //Datatype Registry
-
-    private DatatypeValidatorFactoryImpl fDataTypeReg = 
-    DatatypeValidatorFactoryImpl.getDatatypeRegistry();
-
-    private DatatypeValidator     fValID   = this.fDataTypeReg.getDatatypeValidator("ID" );
-    private DatatypeValidator fValIDRef    = this.fDataTypeReg.getDatatypeValidator("IDREF" );
-    private DatatypeValidator fValIDRefs   = this.fDataTypeReg.getDatatypeValidator("IDREFS" );
-    private DatatypeValidator fValENTITY   = this.fDataTypeReg.getDatatypeValidator("ENTITY" );
-    private DatatypeValidator fValENTITIES = this.fDataTypeReg.getDatatypeValidator("ENTITIES" );
-    private DatatypeValidator fValNMTOKEN  = this.fDataTypeReg.getDatatypeValidator("NMTOKEN");
-    private DatatypeValidator fValNMTOKENS = this.fDataTypeReg.getDatatypeValidator("NMTOKENS");
-    private DatatypeValidator fValNOTATION = this.fDataTypeReg.getDatatypeValidator("NOTATION" );
-
-
-    //
-    // Constructors
-    //
-
-    /** Constructs an XML validator. */
-    public XMLValidator(StringPool stringPool,
-                        XMLErrorReporter errorReporter,
-                        DefaultEntityHandler entityHandler,
-                        XMLDocumentScanner documentScanner) {
-
-        // keep references
-        fStringPool = stringPool;
-        fErrorReporter = errorReporter;
-        fEntityHandler = entityHandler;
-        fDocumentScanner = documentScanner;
-
-        fEmptyURI = fStringPool.addSymbol("");
-        fXsiURI = fStringPool.addSymbol(SchemaSymbols.URI_XSI);
-        // initialize
-        fAttrList = new XMLAttrList(fStringPool);
-        entityHandler.setEventHandler(this);
-        entityHandler.setCharDataHandler(this);
-        fDocumentScanner.setEventHandler(this);
-
-        for (int i = 0; i < sizeQNameParts; i++) {
-            fElementQNamePartsStack[i] = new QName();
-        }
-        init();
-
-    } // <init>(StringPool,XMLErrorReporter,DefaultEntityHandler,XMLDocumentScanner)
-
-    public void setGrammarResolver(GrammarResolver grammarResolver){
-        fGrammarResolver = grammarResolver;
-    }
-
-    //
-    // Public methods
-    //
-
-    // initialization
-
-    /** Set char data processing preference and handlers. */
-    public void initHandlers(boolean sendCharDataAsCharArray,
-                             XMLDocumentHandler docHandler,
-                             XMLDocumentHandler.DTDHandler dtdHandler) {
-
-        fSendCharDataAsCharArray = sendCharDataAsCharArray;
-        fEntityHandler.setSendCharDataAsCharArray(fSendCharDataAsCharArray);
-        fDocumentHandler = docHandler;
-        fDTDHandler = dtdHandler;
-
-    } // initHandlers(boolean,XMLDocumentHandler,XMLDocumentHandler.DTDHandler)
-
-    /** Reset or copy. */
-    public void resetOrCopy(StringPool stringPool) throws Exception {
-        fAttrList = new XMLAttrList(stringPool);
-        resetCommon(stringPool);
-    }
-
-    /** Reset. */
-    public void reset(StringPool stringPool) throws Exception {
-        fAttrList.reset(stringPool);
-        resetCommon(stringPool);
-    }
-
-
-    // settings
-
-    /**
-     * Turning on validation/dynamic turns on validation if it is off, and 
-     * this is remembered.  Turning off validation DISABLES validation/dynamic
-     * if it is on.  Turning off validation/dynamic DOES NOT turn off
-     * validation if it was explicitly turned on, only if it was turned on
-     * BECAUSE OF the call to turn validation/dynamic on.  Turning on
-     * validation will REENABLE and turn validation/dynamic back on if it
-     * was disabled by a call that turned off validation while 
-     * validation/dynamic was enabled.
-     */
-    public void setValidationEnabled(boolean flag) throws Exception {
-        fValidationEnabled = flag;
-        fValidationEnabledByDynamic = false;
-        if (fValidationEnabled) {
-            if (fDynamicDisabledByValidation) {
-                fDynamicValidation = true;
-                fDynamicDisabledByValidation = false;
-            }
-        } else if (fDynamicValidation) {
-            fDynamicValidation = false;
-            fDynamicDisabledByValidation = true;
-        }
-        fValidating = fValidationEnabled;
-    }
-
-    /** Returns true if validation is enabled. */
-    public boolean getValidationEnabled() {
-        return fValidationEnabled;
-    }
-
-    /** Sets whether Schema support is on/off. */
-    public void setSchemaValidationEnabled(boolean flag) {
-        fSchemaValidation = flag;
-    }
-
-    /** Returns true if Schema support is on. */
-    public boolean getSchemaValidationEnabled() {
-        return fSchemaValidation;
-    }
-
-    /** Sets whether validation is dynamic. */
-    public void setDynamicValidationEnabled(boolean flag) throws Exception {
-        fDynamicValidation = flag;
-        fDynamicDisabledByValidation = false;
-        if (!fDynamicValidation) {
-            if (fValidationEnabledByDynamic) {
-                fValidationEnabled = false;
-                fValidationEnabledByDynamic = false;
-            }
-        } else if (!fValidationEnabled) {
-            fValidationEnabled = true;
-            fValidationEnabledByDynamic = true;
-        }
-        fValidating = fValidationEnabled;
-    }
-
-    /** Returns true if validation is dynamic. */
-    public boolean getDynamicValidationEnabled() {
-        return fDynamicValidation;
-    }
-
-    /** Sets fLoadDTDGrammar when validation is off **/
-    public void setLoadDTDGrammar(boolean loadDG){
-        if (fValidating) {
-            fLoadDTDGrammar = true;
-        } else {
-            fLoadDTDGrammar = loadDG;
-        }
-    }
-
-    /** Returns fLoadDTDGrammar **/
-    public boolean getLoadDTDGrammar() {
-        return fLoadDTDGrammar;
-    }
-
-    /** Sets whether namespaces are enabled. */
-    public void setNamespacesEnabled(boolean flag) {
-        fNamespacesEnabled = flag;
-    }
-
-    /** Returns true if namespaces are enabled. */
-    public boolean getNamespacesEnabled() {
-        return fNamespacesEnabled;
-    }
-
-    /** Sets whether duplicate attribute definitions signal a warning. */
-    public void setWarningOnDuplicateAttDef(boolean flag) {
-        fWarningOnDuplicateAttDef = flag;
-    }
-
-    /** Returns true if duplicate attribute definitions signal a warning. */
-    public boolean getWarningOnDuplicateAttDef() {
-        return fWarningOnDuplicateAttDef;
-    }
-
-    /** Sets whether undeclared elements signal a warning. */
-    public void setWarningOnUndeclaredElements(boolean flag) {
-        fWarningOnUndeclaredElements = flag;
-    }
-
-    /** Returns true if undeclared elements signal a warning. */
-    public boolean getWarningOnUndeclaredElements() {
-        return fWarningOnUndeclaredElements;
-    }
-
-    //
-    // DefaultEntityHandler.EventHandler methods
-    //
-
-    /** Start entity reference. */
-    public void startEntityReference(int entityName, int entityType, int entityContext) throws Exception {
-        fDocumentHandler.startEntityReference(entityName, entityType, entityContext);
-    }
-
-    /** End entity reference. */
-    public void endEntityReference(int entityName, int entityType, int entityContext) throws Exception {
-        fDocumentHandler.endEntityReference(entityName, entityType, entityContext);
-    }
-
-    /** Send end of input notification. */
-    public void sendEndOfInputNotifications(int entityName, boolean moreToFollow) throws Exception {
-        fDocumentScanner.endOfInput(entityName, moreToFollow);
-        /***
-        if (fScanningDTD) {
-            fDTDImporter.sendEndOfInputNotifications(entityName, moreToFollow);
-        }
-        /***/
-    }
-
-    /** Send reader change notifications. */
-    public void sendReaderChangeNotifications(XMLEntityHandler.EntityReader reader, int readerId) throws Exception {
-        fDocumentScanner.readerChange(reader, readerId);
-        /***
-        if (fScanningDTD) {
-            fDTDImporter.sendReaderChangeNotifications(reader, readerId);
-        }
-        /***/
-    }
-
-    /** External entity standalone check. */
-    public boolean externalEntityStandaloneCheck() {
-        return(fStandaloneReader != -1 && fValidating);
-    }
-
-    /** Return true if validating. */
-    public boolean getValidating() {
-        return fValidating;
-    }
-
-    //
-    // XMLEntityHandler.CharDataHandler methods
-    //
-
-    /** Process characters. */
-    public void processCharacters(char[] chars, int offset, int length) throws Exception {
-        if (fValidating) {
-            if (fInElementContent || fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
-                charDataInContent();
-            }
-            if (fBufferDatatype) {
-                fDatatypeBuffer.append(chars, offset, length);
-            }
-        }
-        fDocumentHandler.characters(chars, offset, length);
-    }
-
-    /** Process characters. */
-    public void processCharacters(int data) throws Exception {
-        if (fValidating) {
-            if (fInElementContent || fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
-                charDataInContent();
-            }
-            if (fBufferDatatype) {
-                fDatatypeBuffer.append(fStringPool.toString(data));
-            }
-        }
-        fDocumentHandler.characters(data);
-    }
-
-    /** Process whitespace. */
-    public void processWhitespace(char[] chars, int offset, int length) 
-    throws Exception {
-
-        if (fInElementContent) {
-            if (fStandaloneReader != -1 && fValidating && getElementDeclIsExternal(fCurrentElementIndex)) {
-                reportRecoverableXMLError(XMLMessages.MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE,
-                                          XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION);
-            }
-            fDocumentHandler.ignorableWhitespace(chars, offset, length);
-        } else {
-            if (fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
-                charDataInContent();
-            }
-            fDocumentHandler.characters(chars, offset, length);
-        }
-
-    } // processWhitespace(char[],int,int)
-
-    /** Process whitespace. */
-    public void processWhitespace(int data) throws Exception {
-
-        if (fInElementContent) {
-            if (fStandaloneReader != -1 && fValidating && getElementDeclIsExternal(fCurrentElementIndex)) {
-                reportRecoverableXMLError(XMLMessages.MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE,
-                                          XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION);
-            }
-            fDocumentHandler.ignorableWhitespace(data);
-        } else {
-            if (fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
-                charDataInContent();
-            }
-            fDocumentHandler.characters(data);
-        }
-
-    } // processWhitespace(int)
-
-    //
-    // XMLDocumentScanner.EventHandler methods
-    //
-
-    /** Scans element type. */
-    public void scanElementType(XMLEntityHandler.EntityReader entityReader, 
-                                char fastchar, QName element) throws Exception {
-
-        if (!fNamespacesEnabled) {
-            element.clear();
-            element.localpart = entityReader.scanName(fastchar);
-            element.rawname = element.localpart;
-        } else {
-            entityReader.scanQName(fastchar, element);
-            if (entityReader.lookingAtChar(':', false)) {
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_TWO_COLONS_IN_QNAME,
-                                           XMLMessages.P5_INVALID_CHARACTER,
-                                           null,
-                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-                entityReader.skipPastNmtoken(' ');
-            }
-        }
-
-    } // scanElementType(XMLEntityHandler.EntityReader,char,QName)
-
-    /** Scans expected element type. */
-    public boolean scanExpectedElementType(XMLEntityHandler.EntityReader entityReader, 
-                                           char fastchar, QName element) 
-    throws Exception {
-
-        if (fCurrentElementCharArrayRange == null) {
-            fCurrentElementCharArrayRange = fStringPool.createCharArrayRange();
-        }
-        fStringPool.getCharArrayRange(fCurrentElement.rawname, fCurrentElementCharArrayRange);
-        return entityReader.scanExpectedName(fastchar, fCurrentElementCharArrayRange);
-
-    } // scanExpectedElementType(XMLEntityHandler.EntityReader,char,QName)
-
-    /** Scans attribute name. */
-    public void scanAttributeName(XMLEntityHandler.EntityReader entityReader, 
-                                  QName element, QName attribute) 
-    throws Exception {
-
-        if (!fSeenRootElement) {
-            fSeenRootElement = true;
-            rootElementSpecified(element);
-            fStringPool.resetShuffleCount();
-        }
-
-        if (!fNamespacesEnabled) {
-            attribute.clear();
-            attribute.localpart = entityReader.scanName('=');
-            attribute.rawname = attribute.localpart;
-        } else {
-            entityReader.scanQName('=', attribute);
-            if (entityReader.lookingAtChar(':', false)) {
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XML_DOMAIN,
-                                           XMLMessages.MSG_TWO_COLONS_IN_QNAME,
-                                           XMLMessages.P5_INVALID_CHARACTER,
-                                           null,
-                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-                entityReader.skipPastNmtoken(' ');
-            }
-        }
-
-    } // scanAttributeName(XMLEntityHandler.EntityReader,QName,QName)
-
-    /** Call start document. */
-    public void callStartDocument() throws Exception {
-
-        if (!fCalledStartDocument) {
-            fDocumentHandler.startDocument();
-            fCalledStartDocument = true;
-        }
-    }
-
-    /** Call end document. */
-    public void callEndDocument() throws Exception {
-
-        if (fCalledStartDocument) {
-            fDocumentHandler.endDocument();
-        }
-    }
-
-    /** Call XML declaration. */
-    public void callXMLDecl(int version, int encoding, int standalone) throws Exception {
-        fDocumentHandler.xmlDecl(version, encoding, standalone);
-    }
-    public void callStandaloneIsYes() throws Exception {
-        // standalone = "yes". said XMLDocumentScanner.
-        fStandaloneReader = fEntityHandler.getReaderId() ;
-
-    }
-
-
-
-    /** Call text declaration. */
-    public void callTextDecl(int version, int encoding) throws Exception {
-        fDocumentHandler.textDecl(version, encoding);
-    }
-
-    /**
-     * Signal the scanning of an element name in a start element tag.
-     *
-     * @param element Element name scanned.
-     */
-    public void element(QName element) throws Exception {
-        fAttrListHandle = -1;
-    }
-    /**
-     * Signal the scanning of an attribute associated to the previous
-     * start element tag.
-     *
-     * @param element Element name scanned.
-     * @param attrName Attribute name scanned.
-     * @param attrValue The string pool index of the attribute value.
-     */
-    public boolean attribute(QName element, QName attrName, int attrValue) throws Exception {
-        if (fAttrListHandle == -1) {
-            fAttrListHandle = fAttrList.startAttrList();
-        }
-
-        // if fAttrList.addAttr returns -1, indicates duplicate att in start tag of an element.
-        // specified: true, search : true
-        return fAttrList.addAttr(attrName, attrValue, fCDATASymbol, true, true) == -1;
-    }
-
-    /** Call start element. */
-    public void callStartElement(QName element) throws Exception {
-
-        if ( DEBUG_SCHEMA_VALIDATION )
-            System.out.println("\n=======StartElement : " + fStringPool.toString(element.localpart));
-
-
-        //
-        // Check after all specified attrs are scanned
-        // (1) report error for REQUIRED attrs that are missing (V_TAGc)
-        // (2) add default attrs (FIXED and NOT_FIXED)
-        //
-
-        if (!fSeenRootElement) {
-            fSeenRootElement = true;
-            rootElementSpecified(element);
-            fStringPool.resetShuffleCount();
-        }
-
-        if (fGrammar != null && fGrammarIsDTDGrammar) {
-            fAttrListHandle = addDTDDefaultAttributes(element, fAttrList, fAttrListHandle, fValidating, fStandaloneReader != -1);
-        }
-
-        fCheckedForSchema = true;
-        if (fNamespacesEnabled) {
-            bindNamespacesToElementAndAttributes(element, fAttrList);
-        }
-
-        validateElementAndAttributes(element, fAttrList);
-        if (fAttrListHandle != -1) {
-            fAttrList.endAttrList();
-        }
-
-        fDocumentHandler.startElement(element, fAttrList, fAttrListHandle);
-        fAttrListHandle = -1;
-
-        //before we increment the element depth, add this element's QName to its enclosing element 's children list
-        fElementDepth++;
-        //if (fElementDepth >= 0) {
-        if (fValidating) {
-            // push current length onto stack
-            if (fElementChildrenOffsetStack.length < fElementDepth) {
-                int newarray[] = new int[fElementChildrenOffsetStack.length * 2];
-                System.arraycopy(fElementChildrenOffsetStack, 0, newarray, 0, fElementChildrenOffsetStack.length);
-                fElementChildrenOffsetStack = newarray;
-            }
-            fElementChildrenOffsetStack[fElementDepth] = fElementChildrenLength;
-
-            // add this element to children
-            if (fElementChildren.length <= fElementChildrenLength) {
-                QName[] newarray = new QName[fElementChildrenLength * 2];
-                System.arraycopy(fElementChildren, 0, newarray, 0, fElementChildren.length);
-                fElementChildren = newarray;
-            }
-            QName qname = fElementChildren[fElementChildrenLength];
-            if (qname == null) {
-                for (int i = fElementChildrenLength; i < fElementChildren.length; i++) {
-                    fElementChildren[i] = new QName();
-                }
-                qname = fElementChildren[fElementChildrenLength];
-            }
-            qname.setValues(element);
-            fElementChildrenLength++;
-
-            if (DEBUG_ELEMENT_CHILDREN) {
-                printChildren();
-                printStack();
-            }
-        }
-
-        // One more level of depth
-        //fElementDepth++;
-
-        ensureStackCapacity(fElementDepth);
-        fCurrentElement.setValues(element);
-        fCurrentElementEntity = fEntityHandler.getReaderId();
-
-        fElementQNamePartsStack[fElementDepth].setValues(fCurrentElement); 
-
-        fElementEntityStack[fElementDepth] = fCurrentElementEntity;
-        fElementIndexStack[fElementDepth] = fCurrentElementIndex;
-        fContentSpecTypeStack[fElementDepth] = fCurrentContentSpecType;
-
-        if (fNeedValidationOff) {
-            fValidating = false;
-            fNeedValidationOff = false;
-        }
-
-        if (fValidating && fGrammarIsSchemaGrammar) {
-            pushContentLeafStack();
-        }
-
-        fValidationFlagStack[fElementDepth] = fValidating ? 0 : -1;
-
-        fScopeStack[fElementDepth] = fCurrentScope;
-        fGrammarNameSpaceIndexStack[fElementDepth] = fGrammarNameSpaceIndex;
-
-    } // callStartElement(QName)
-
-    private void pushContentLeafStack() throws Exception {
-        int contentType = getContentSpecType(fCurrentElementIndex);
-        if ( contentType == XMLElementDecl.TYPE_CHILDREN) {
-            XMLContentModel cm = getElementContentModel(fCurrentElementIndex);
-            ContentLeafNameTypeVector cv = cm.getContentLeafNameTypeVector();
-            if (cm != null) {
-                fContentLeafStack[fElementDepth] = cv;
-            }
-        }
-    }
-
-    private void ensureStackCapacity ( int newElementDepth) {
-
-        if (newElementDepth == fElementQNamePartsStack.length ) {
-            int[] newStack = new int[newElementDepth * 2];
-            System.arraycopy(fScopeStack, 0, newStack, 0, newElementDepth);
-            fScopeStack = newStack;
-
-            newStack = new int[newElementDepth * 2];
-            System.arraycopy(fGrammarNameSpaceIndexStack, 0, newStack, 0, newElementDepth);
-            fGrammarNameSpaceIndexStack = newStack;
-
-            QName[] newStackOfQueue = new QName[newElementDepth * 2];
-            System.arraycopy(this.fElementQNamePartsStack, 0, newStackOfQueue, 0, newElementDepth );
-            fElementQNamePartsStack      = newStackOfQueue;
-
-            QName qname = fElementQNamePartsStack[newElementDepth];
-            if (qname == null) {
-                for (int i = newElementDepth; i < fElementQNamePartsStack.length; i++) {
-                    fElementQNamePartsStack[i] = new QName();
-                }
-            }
-
-            newStack = new int[newElementDepth * 2];
-            System.arraycopy(fElementEntityStack, 0, newStack, 0, newElementDepth);
-            fElementEntityStack = newStack;
-
-            newStack = new int[newElementDepth * 2];
-            System.arraycopy(fElementIndexStack, 0, newStack, 0, newElementDepth);
-            fElementIndexStack = newStack;
-
-            newStack = new int[newElementDepth * 2];
-            System.arraycopy(fContentSpecTypeStack, 0, newStack, 0, newElementDepth);
-            fContentSpecTypeStack = newStack;
-
-            newStack = new int[newElementDepth * 2];
-            System.arraycopy(fValidationFlagStack, 0, newStack, 0, newElementDepth);
-            fValidationFlagStack = newStack;
-
-            ContentLeafNameTypeVector[] newStackV = new ContentLeafNameTypeVector[newElementDepth * 2];
-            System.arraycopy(fContentLeafStack, 0, newStackV, 0, newElementDepth);
-            fContentLeafStack = newStackV;
-        }
-    }
-
-    /** Call end element. */
-    public void callEndElement(int readerId) throws Exception {
-        if ( DEBUG_SCHEMA_VALIDATION )
-            System.out.println("=======EndElement : " + fStringPool.toString(fCurrentElement.localpart)+"\n");
-
-        int prefixIndex = fCurrentElement.prefix;
-        int elementType = fCurrentElement.rawname;
-
-        if (fCurrentElementEntity != readerId) {
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                       XMLMessages.XML_DOMAIN,
-                                       XMLMessages.MSG_ELEMENT_ENTITY_MISMATCH,
-                                       XMLMessages.P78_NOT_WELLFORMED,
-                                       new Object[] { fStringPool.toString(elementType)},
-                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-        }
-
-        fElementDepth--;
-        if (fValidating) {
-            int elementIndex = fCurrentElementIndex;
-            if (elementIndex != -1 && fCurrentContentSpecType != -1) {
-                QName children[] = fElementChildren;
-                int childrenOffset = fElementChildrenOffsetStack[fElementDepth + 1] + 1;
-                int childrenLength = fElementChildrenLength - childrenOffset;
-                if (DEBUG_ELEMENT_CHILDREN) {
-                    System.out.println("endElement("+fStringPool.toString(fCurrentElement.rawname)+')');
-                    System.out.println("fCurrentContentSpecType : " + fCurrentContentSpecType );
-                    System.out.print("offset: ");
-                    System.out.print(childrenOffset);
-                    System.out.print(", length: ");
-                    System.out.print(childrenLength);
-                    System.out.println();
-                    printChildren();
-                    printStack();
-                }
-                int result = checkContent(elementIndex, 
-                                          children, childrenOffset, childrenLength);
-
-                if ( DEBUG_SCHEMA_VALIDATION )
-                    System.out.println("!!!!!!!!In XMLValidator, the return value from checkContent : " + result);
-
-                if (result != -1) {
-                    int majorCode = result != childrenLength ? XMLMessages.MSG_CONTENT_INVALID : XMLMessages.MSG_CONTENT_INCOMPLETE;
-                    fGrammar.getElementDecl(elementIndex, fTempElementDecl);
-                    if (fTempElementDecl.type == XMLElementDecl.TYPE_EMPTY) {
-                        reportRecoverableXMLError(majorCode,
-                                                  0,
-                                                  fStringPool.toString(elementType),
-                                                  "EMPTY");
-                    } else
-                        reportRecoverableXMLError(majorCode,
-                                                  0,
-                                                  fStringPool.toString(elementType),
-                                                  XMLContentSpec.toString(fGrammar, fStringPool, fTempElementDecl.contentSpecIndex));
-                }
-            }
-            fElementChildrenLength = fElementChildrenOffsetStack[fElementDepth + 1] + 1;
-        }
-        fDocumentHandler.endElement(fCurrentElement);
-        if (fNamespacesEnabled) {
-            fNamespacesScope.decreaseDepth();
-        }
-
-        // now pop this element off the top of the element stack
-        //if (fElementDepth-- < 0) {
-        if (fElementDepth < -1) {
-            throw new RuntimeException("FWK008 Element stack underflow");
-        }
-        if (fElementDepth < 0) {
-            fCurrentElement.clear();
-            fCurrentElementEntity = -1;
-            fCurrentElementIndex = -1;
-            fCurrentContentSpecType = -1;
-            fInElementContent = false;
-            //
-            // Check after document is fully parsed
-            // (1) check that there was an element with a matching id for every
-            //   IDREF and IDREFS attr (V_IDREF0)
-            //
-            if (fValidating ) {
-                try {
-                    this.fValIDRef.validate( null, this.fValidateIDRef );   
-                    this.fValIDRefs.validate( null, this.fValidateIDRef );
-                } catch ( InvalidDatatypeValueException ex ) {
-                    reportRecoverableXMLError( ex.getMajorCode(), ex.getMinorCode(), 
-                                               ex.getMessage() ); 
-
-
-                }
-            }
-            
-            try {//Reset datatypes state
-               this.fValID.validate( null, this.fResetID );
-               this.fValIDRef.validate(null, this.fResetIDRef );
-               this.fValIDRefs.validate(null, this.fResetIDRef );
-            } catch ( InvalidDatatypeValueException ex ) {
-                System.err.println("Error re-Initializing: ID,IDRef,IDRefs pools" );
-            }
-            return;
-        }
-
-
-        //restore enclosing element to all the "current" variables
-        // REVISIT: Validation. This information needs to be stored.
-        fCurrentElement.prefix = -1;
-
-
-        if (fNamespacesEnabled) { //If Namespace enable then localName != rawName
-            fCurrentElement.localpart = fElementQNamePartsStack[fElementDepth].localpart;
-        } else {//REVISIT - jeffreyr - This is so we still do old behavior when namespace is off 
-            fCurrentElement.localpart = fElementQNamePartsStack[fElementDepth].rawname;
-        }
-        fCurrentElement.rawname      = fElementQNamePartsStack[fElementDepth].rawname;
-        fCurrentElement.uri          = fElementQNamePartsStack[fElementDepth].uri;
-        fCurrentElement.prefix       = fElementQNamePartsStack[fElementDepth].prefix;
-
-
-        fCurrentElementEntity = fElementEntityStack[fElementDepth];
-        fCurrentElementIndex = fElementIndexStack[fElementDepth];
-        fCurrentContentSpecType = fContentSpecTypeStack[fElementDepth];
-
-        fValidating = fValidationFlagStack[fElementDepth] == 0 ? true : false;
-
-        fCurrentScope = fScopeStack[fElementDepth];  
-
-        //if ( DEBUG_SCHEMA_VALIDATION ) {
-
-/****
-System.out.println("+++++ currentElement : " + fStringPool.toString(elementType)+
-                   "\n fCurrentElementIndex : " + fCurrentElementIndex +
-                   "\n fCurrentScope : " + fCurrentScope +
-                   "\n fCurrentContentSpecType : " + fCurrentContentSpecType +
-                   "\n++++++++++++++++++++++++++++++++++++++++++++++++" );
-/****/
-        //}
-
-        // if enclosing element's Schema is different, need to switch "context"
-        if ( fGrammarNameSpaceIndex != fGrammarNameSpaceIndexStack[fElementDepth] ) {
-            fGrammarNameSpaceIndex = fGrammarNameSpaceIndexStack[fElementDepth];
-            if ( fValidating && fGrammarIsSchemaGrammar )
-                if ( !switchGrammar(fGrammarNameSpaceIndex) ) {
-                    reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR, 
-                                              "Grammar with uri : " + fStringPool.toString(fGrammarNameSpaceIndex) 
-                                              + " , can not found");
-                }
-        }
-
-        if (fValidating) {
-            fBufferDatatype = false;
-        }
-        fInElementContent = (fCurrentContentSpecType == XMLElementDecl.TYPE_CHILDREN);
-
-    } // callEndElement(int)
-
-    /** Call start CDATA section. */
-    public void callStartCDATA() throws Exception {
-        fDocumentHandler.startCDATA();
-    }
-
-    /** Call end CDATA section. */
-    public void callEndCDATA() throws Exception {
-        fDocumentHandler.endCDATA();
-    }
-
-    /** Call characters. */
-    public void callCharacters(int ch) throws Exception {
-
-        if (fCharRefData == null) {
-            fCharRefData = new char[2];
-        }
-        int count = (ch < 0x10000) ? 1 : 2;
-        if (count == 1) {
-            fCharRefData[0] = (char)ch;
-        } else {
-            fCharRefData[0] = (char)(((ch-0x00010000)>>10)+0xd800);
-            fCharRefData[1] = (char)(((ch-0x00010000)&0x3ff)+0xdc00);
-        }
-        if (fValidating && (fInElementContent || fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY)) {
-            charDataInContent();
-        }
-        if (fSendCharDataAsCharArray) {
-            fDocumentHandler.characters(fCharRefData, 0, count);
-        } else {
-            int index = fStringPool.addString(new String(fCharRefData, 0, count));
-            fDocumentHandler.characters(index);
-        }
-
-    } // callCharacters(int)
-
-    /** Call processing instruction. */
-    public void callProcessingInstruction(int target, int data) throws Exception {
-        fDocumentHandler.processingInstruction(target, data);
-    }
-
-    /** Call comment. */
-    public void callComment(int comment) throws Exception {
-        fDocumentHandler.comment(comment);
-    }
-
-    //
-    // NamespacesScope.NamespacesHandler methods
-    //
-
-    /** Start a new namespace declaration scope. */
-    public void startNamespaceDeclScope(int prefix, int uri) throws Exception {
-        fDocumentHandler.startNamespaceDeclScope(prefix, uri);
-    }
-
-    /** End a namespace declaration scope. */
-    public void endNamespaceDeclScope(int prefix) throws Exception {
-        fDocumentHandler.endNamespaceDeclScope(prefix);
-    }
-
-    // attributes
-
-
-    // other
-
-    /** Sets the root element. */
-    public void setRootElementType(QName rootElement) {
-        fRootElement.setValues(rootElement);
-    }
-
-    /** 
-     * Returns true if the element declaration is external. 
-     * <p>
-     * <strong>Note:</strong> This method is primarilly useful for
-     * DTDs with internal and external subsets.
-     */
-    private boolean getElementDeclIsExternal(int elementIndex) {
-        /*if (elementIndex < 0 || elementIndex >= fElementCount) {
-            return false;
-        }
-        int chunk = elementIndex >> CHUNK_SHIFT;
-        int index = elementIndex & CHUNK_MASK;
-        return (fElementDeclIsExternal[chunk][index] != 0);
-        */
-
-        if (fGrammarIsDTDGrammar ) {
-            return((DTDGrammar) fGrammar).getElementDeclIsExternal(elementIndex);
-        }
-        return false;
-    }
-
-    /** Returns the content spec type for an element index. */
-    public int getContentSpecType(int elementIndex) {
-
-        int contentSpecType = -1;
-        if ( elementIndex > -1) {
-            if ( fGrammar.getElementDecl(elementIndex,fTempElementDecl) ) {
-                contentSpecType = fTempElementDecl.type;
-            }
-        }
-        return contentSpecType;
-    }
-
-    /** Returns the content spec handle for an element index. */
-    public int getContentSpecHandle(int elementIndex) {
-        int contentSpecHandle = -1;
-        if ( elementIndex > -1) {
-            if ( fGrammar.getElementDecl(elementIndex,fTempElementDecl) ) {
-                contentSpecHandle = fTempElementDecl.contentSpecIndex;
-            }
-        }
-        return contentSpecHandle;
-    }
-
-    //
-    // Protected methods
-    //
-
-    // error reporting
-
-    /** Report a recoverable xml error. */
-    protected void reportRecoverableXMLError(int majorCode, int minorCode) 
-    throws Exception {
-
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   null,
-                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-
-    } // reportRecoverableXMLError(int,int)
-
-    /** Report a recoverable xml error. */
-    protected void reportRecoverableXMLError(int majorCode, int minorCode, 
-                                             int stringIndex1) 
-    throws Exception {
-
-        Object[] args = { fStringPool.toString(stringIndex1)};
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-
-    } // reportRecoverableXMLError(int,int,int)
-
-    /** Report a recoverable xml error. */
-    protected void reportRecoverableXMLError(int majorCode, int minorCode, 
-                                             String string1) throws Exception {
-
-        Object[] args = { string1};
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-
-    } // reportRecoverableXMLError(int,int,String)
-
-    /** Report a recoverable xml error. */
-    protected void reportRecoverableXMLError(int majorCode, int minorCode, 
-                                             int stringIndex1, int stringIndex2) 
-    throws Exception {
-
-        Object[] args = { fStringPool.toString(stringIndex1), fStringPool.toString(stringIndex2)};
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-
-    } // reportRecoverableXMLError(int,int,int,int)
-
-    /** Report a recoverable xml error. */
-    protected void reportRecoverableXMLError(int majorCode, int minorCode, 
-                                             String string1, String string2) 
-    throws Exception {
-
-        Object[] args = { string1, string2};
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-
-    } // reportRecoverableXMLError(int,int,String,String)
-
-    /** Report a recoverable xml error. */
-    protected void reportRecoverableXMLError(int majorCode, int minorCode, 
-                                             String string1, String string2, 
-                                             String string3) throws Exception {
-
-        Object[] args = { string1, string2, string3};
-        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                   XMLMessages.XML_DOMAIN,
-                                   majorCode,
-                                   minorCode,
-                                   args,
-                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-
-    } // reportRecoverableXMLError(int,int,String,String,String)
-
-    // content spec
-
-    /**
-     * Returns information about which elements can be placed at a particular point
-     * in the passed element's content model.
-     * <p>
-     * Note that the incoming content model to test must be valid at least up to
-     * the insertion point. If not, then -1 will be returned and the info object
-     * will not have been filled in.
-     * <p>
-     * If, on return, the info.isValidEOC flag is set, then the 'insert after'
-     * elemement is a valid end of content, i.e. nothing needs to be inserted
-     * after it to make the parent element's content model valid.
-     *
-     * @param elementIndex The index within the <code>ElementDeclPool</code> of the
-     *                     element which is being querying.
-     * @param fullyValid Only return elements that can be inserted and still
-     *                   maintain the validity of subsequent elements past the
-     *                   insertion point (if any).  If the insertion point is at
-     *                   the end, and this is true, then only elements that can
-     *                   be legal final states will be returned.
-     * @param info An object that contains the required input data for the method,
-     *             and which will contain the output information if successful.
-     *
-     * @return The value -1 if fully valid, else the 0 based index of the child
-     *         that first failed before the insertion point. If the value
-     *         returned is equal to the number of children, then the specified
-     *         children are valid but additional content is required to reach a
-     *         valid ending state.
-     *
-     * @exception Exception Thrown on error.
-     *
-     * @see InsertableElementsInfo
-     */
-    protected int whatCanGoHere(int elementIndex, boolean fullyValid,
-                                InsertableElementsInfo info) throws Exception {
-
-        //
-        //  Do some basic sanity checking on the info packet. First, make sure
-        //  that insertAt is not greater than the child count. It can be equal,
-        //  which means to get appendable elements, but not greater. Or, if
-        //  the current children array is null, that's bad too.
-        //
-        //  Since the current children array must have a blank spot for where
-        //  the insert is going to be, the child count must always be at least
-        //  one.
-        //
-        //  Make sure that the child count is not larger than the current children
-        //  array. It can be equal, which means get appendable elements, but not
-        //  greater.
-        //
-        if (info.insertAt > info.childCount || info.curChildren == null ||  
-            info.childCount < 1 || info.childCount > info.curChildren.length) {
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                       ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
-                                       ImplementationMessages.VAL_WCGHI,
-                                       0,
-                                       null,
-                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-        }
-
-        int retVal = 0;
-        try {
-            // Get the content model for this element
-            final XMLContentModel cmElem = getElementContentModel(elementIndex);
-
-            // And delegate this call to it
-            retVal = cmElem.whatCanGoHere(fullyValid, info);
-        } catch (CMException excToCatch) {
-            // REVISIT - Translate caught error to the protected error handler interface
-            int majorCode = excToCatch.getErrorCode();
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                       ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
-                                       majorCode,
-                                       0,
-                                       null,
-                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            throw excToCatch;
-        }
-        return retVal;
-
-    } // whatCanGoHere(int,boolean,InsertableElementsInfo):int
-
-    // attribute information
-
-    /** Protected for use by AttributeValidator classes. */
-    protected boolean getAttDefIsExternal(QName element, QName attribute) {
-        int attDefIndex = getAttDef(element, attribute);
-        if (fGrammarIsDTDGrammar ) {
-            return((DTDGrammar) fGrammar).getAttributeDeclIsExternal(attDefIndex);
-        }
-        return false;
-    }
-
-
-
-    //
-    // Private methods
-    //
-
-    // other
-
-    /** Returns true if using a standalone reader. */
-    private boolean usingStandaloneReader() {
-        return fStandaloneReader == -1 || fEntityHandler.getReaderId() == fStandaloneReader;
-    }
-
-    /** Returns a locator implementation. */
-    private LocatorImpl getLocatorImpl(LocatorImpl fillin) {
-
-        Locator here = fErrorReporter.getLocator();
-        if (fillin == null)
-            return new LocatorImpl(here);
-        fillin.setPublicId(here.getPublicId());
-        fillin.setSystemId(here.getSystemId());
-        fillin.setLineNumber(here.getLineNumber());
-        fillin.setColumnNumber(here.getColumnNumber());
-        return fillin;
-
-    } // getLocatorImpl(LocatorImpl):LocatorImpl
-
-
-    // initialization
-
-    /** Reset pool. */
-    private void poolReset() {
-        try {
-            //System.out.println("We reset" );
-            this.fValID.validate( null, this.fResetID );
-            this.fValIDRef.validate(null, this.fResetIDRef );
-            this.fValIDRefs.validate(null, this.fResetIDRef );
-        } catch ( InvalidDatatypeValueException ex ) {
-            System.err.println("Error re-Initializing: ID,IDRef,IDRefs pools" );
-        }
-    } // poolReset()
-
-    /** Reset common. */
-    private void resetCommon(StringPool stringPool) throws Exception {
-
-        fStringPool = stringPool;
-        fValidating = fValidationEnabled;
-        fValidationEnabledByDynamic = false;
-        fDynamicDisabledByValidation = false;
-        poolReset();
-        fCalledStartDocument = false;
-        fStandaloneReader = -1;
-        fElementChildrenLength = 0;
-        fElementDepth = -1;
-        fSeenRootElement = false;
-        fSeenDoctypeDecl = false;
-        fNamespacesScope = null;
-        fNamespacesPrefix = -1;
-        fRootElement.clear();
-        fAttrListHandle = -1;
-        fCheckedForSchema = false;
-
-        fCurrentScope = TOP_LEVEL_SCOPE;
-        fCurrentSchemaURI = -1;
-        fEmptyURI = - 1; 
-        fXsiPrefix = - 1;
-        fXsiTypeValidator = null;
-
-        fGrammar = null;
-        fGrammarNameSpaceIndex = -1;
-        //fGrammarResolver = null;
-        if (fGrammarResolver != null) {
-            fGrammarResolver.clearGrammarResolver();
-        }
-        fGrammarIsDTDGrammar = false;
-        fGrammarIsSchemaGrammar = false;
-
-
-        init();
-
-    } // resetCommon(StringPool)
-
-    /** Initialize. */
-    private void init() {
-
-        fEmptyURI = fStringPool.addSymbol("");
-        fXsiURI = fStringPool.addSymbol(SchemaSymbols.URI_XSI);
-
-
-        fEMPTYSymbol = fStringPool.addSymbol("EMPTY");
-        fANYSymbol = fStringPool.addSymbol("ANY");
-        fMIXEDSymbol = fStringPool.addSymbol("MIXED");
-        fCHILDRENSymbol = fStringPool.addSymbol("CHILDREN");
-
-        fCDATASymbol = fStringPool.addSymbol("CDATA");
-        fIDSymbol = fStringPool.addSymbol("ID");
-        fIDREFSymbol = fStringPool.addSymbol("IDREF");
-        fIDREFSSymbol = fStringPool.addSymbol("IDREFS");
-        fENTITYSymbol = fStringPool.addSymbol("ENTITY");
-        fENTITIESSymbol = fStringPool.addSymbol("ENTITIES");
-        fNMTOKENSymbol = fStringPool.addSymbol("NMTOKEN");
-        fNMTOKENSSymbol = fStringPool.addSymbol("NMTOKENS");
-        fNOTATIONSymbol = fStringPool.addSymbol("NOTATION");
-        fENUMERATIONSymbol = fStringPool.addSymbol("ENUMERATION");
-        fREQUIREDSymbol = fStringPool.addSymbol("#REQUIRED");
-        fFIXEDSymbol = fStringPool.addSymbol("#FIXED");
-        fDATATYPESymbol = fStringPool.addSymbol("<<datatype>>");
-        fEpsilonIndex = fStringPool.addSymbol("<<CMNODE_EPSILON>>");
-        fXMLLang = fStringPool.addSymbol("xml:lang");
-
-        try {//Initialize ENTITIES and ENTITY Validators
-            Object[] packageArgsEntityVal = { (Object) this.fEntityHandler,
-                (Object) this.fStringPool};
-            fValidateENTITYMsg.setDatatypeObject( (Object ) packageArgsEntityVal);
-            fValENTITIES.validate( null, fValidateENTITYMsg );
-            fValENTITY.validate( null, fValidateENTITYMsg );
-        } catch ( InvalidDatatypeValueException ex ) {
-            System.err.println("Error: " + ex.getLocalizedMessage() );//Should not happen
-        }
-
-
-    } // init()
-
-    // other
-
-    // default attribute
-
-    /** addDefaultAttributes. */
-    private int addDefaultAttributes(int elementIndex, XMLAttrList attrList, int attrIndex, boolean validationEnabled, boolean standalone) throws Exception {
-
-        //System.out.println("XMLValidator#addDefaultAttributes");
-        //System.out.print("  ");
-        //fGrammar.printAttributes(elementIndex);
-
-        //
-        // Check after all specified attrs are scanned
-        // (1) report error for REQUIRED attrs that are missing (V_TAGc)
-        // (2) check that FIXED attrs have matching value (V_TAGd)
-        // (3) add default attrs (FIXED and NOT_FIXED)
-        //
-        fGrammar.getElementDecl(elementIndex,fTempElementDecl);
-
-        int elementNameIndex = fTempElementDecl.name.localpart;
-        int attlistIndex = fGrammar.getFirstAttributeDeclIndex(elementIndex);
-        int firstCheck = attrIndex;
-        int lastCheck = -1;
-        while (attlistIndex != -1) {
-            fGrammar.getAttributeDecl(attlistIndex, fTempAttDecl);
-
-
-            int attPrefix = fTempAttDecl.name.prefix;
-            int attName = fTempAttDecl.name.localpart;
-            int attType = attributeTypeName(fTempAttDecl);
-            int attDefType =fTempAttDecl.defaultType;
-            int attValue = -1 ;
-            if (fTempAttDecl.defaultValue != null ) {
-                attValue = fStringPool.addSymbol(fTempAttDecl.defaultValue);
-            }
-
-            boolean specified = false;
-            boolean required = attDefType == XMLAttributeDecl.DEFAULT_TYPE_REQUIRED;
-
-            if (firstCheck != -1) {
-                boolean cdata = attType == fCDATASymbol;
-                if (!cdata || required || attValue != -1) {
-                    int i = attrList.getFirstAttr(firstCheck);
-                    while (i != -1 && (lastCheck == -1 || i <= lastCheck)) {
-
-                        if ( (fGrammarIsDTDGrammar && (attrList.getAttrName(i) == fTempAttDecl.name.rawname)) ||
-                             (  fStringPool.equalNames(attrList.getAttrLocalpart(i), attName)
-                                && fStringPool.equalNames(attrList.getAttrURI(i), fTempAttDecl.name.uri) ) ) {
-
-                            if (validationEnabled && attDefType == XMLAttributeDecl.DEFAULT_TYPE_FIXED) {
-                                int alistValue = attrList.getAttValue(i);
-                                if (alistValue != attValue &&
-                                    !fStringPool.toString(alistValue).equals(fStringPool.toString(attValue))) {
-                                    Object[] args = { fStringPool.toString(elementNameIndex),
-                                        fStringPool.toString(attName),
-                                        fStringPool.toString(alistValue),
-                                        fStringPool.toString(attValue)};
-                                    fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                                               XMLMessages.XML_DOMAIN,
-                                                               XMLMessages.MSG_FIXED_ATTVALUE_INVALID,
-                                                               XMLMessages.VC_FIXED_ATTRIBUTE_DEFAULT,
-                                                               args,
-                                                               XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                                }
-                            }
-                            specified = true;
-                            break;
-                        }
-                        i = attrList.getNextAttr(i);
-                    }
-                }
-            }
-
-            if (!specified) {
-                if (required) {
-                    if (validationEnabled) {
-                        Object[] args = { fStringPool.toString(elementNameIndex),
-                            fStringPool.toString(attName)};
-                        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                                   XMLMessages.XML_DOMAIN,
-                                                   XMLMessages.MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED,
-                                                   XMLMessages.VC_REQUIRED_ATTRIBUTE,
-                                                   args,
-                                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                    }
-                } else if (attValue != -1) {
-                    if (validationEnabled && standalone )
-                        if ( fGrammarIsDTDGrammar 
-                             && ((DTDGrammar) fGrammar).getAttributeDeclIsExternal(attlistIndex) ) {
-
-                            Object[] args = { fStringPool.toString(elementNameIndex),
-                                fStringPool.toString(attName)};
-                            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                                       XMLMessages.XML_DOMAIN,
-                                                       XMLMessages.MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED,
-                                                       XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
-                                                       args,
-                                                       XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                        }
-                    if (attType == fIDREFSymbol) {
-                        this.fValIDRef.validate( fStringPool.toString(attValue), this.fStoreIDRef );
-                    } else if (attType == fIDREFSSymbol) {
-                        this.fValIDRefs.validate( fStringPool.toString(attValue), this.fStoreIDRef );
-                    }
-                    if (attrIndex == -1) {
-                        attrIndex = attrList.startAttrList();
-                    }
-                    // REVISIT: Validation. What should the prefix be?
-                    fTempQName.setValues(attPrefix, attName, attName, fTempAttDecl.name.uri);
-                    int newAttr = attrList.addAttr(fTempQName, 
-                                                   attValue, attType, 
-                                                   false, false);
-                    if (lastCheck == -1) {
-                        lastCheck = newAttr;
-                    }
-                }
-            }
-            attlistIndex = fGrammar.getNextAttributeDeclIndex(attlistIndex);
-        }
-        return attrIndex;
-
-    } // addDefaultAttributes(int,XMLAttrList,int,boolean,boolean):int
-
-    /** addDTDDefaultAttributes. */
-    private int addDTDDefaultAttributes(QName element, XMLAttrList attrList, int attrIndex, boolean validationEnabled, boolean standalone) throws Exception {
-
-
-        //
-        // Check after all specified attrs are scanned
-        // (1) report error for REQUIRED attrs that are missing (V_TAGc)
-        // (2) check that FIXED attrs have matching value (V_TAGd)
-        // (3) add default attrs (FIXED and NOT_FIXED)
-        //
-
-        int elementIndex = fGrammar.getElementDeclIndex(element, -1);
-
-        if (elementIndex == -1) {
-            return attrIndex;
-        }
-
-        fGrammar.getElementDecl(elementIndex,fTempElementDecl);
-
-
-        int elementNameIndex = fTempElementDecl.name.rawname;
-        int attlistIndex = fGrammar.getFirstAttributeDeclIndex(elementIndex);
-        int firstCheck = attrIndex;
-        int lastCheck = -1;
-        while (attlistIndex != -1) {
-
-            fGrammar.getAttributeDecl(attlistIndex, fTempAttDecl);
-
-            // TO DO: For ericye Debug only
-            /***
-            if (fTempAttDecl != null) {
-                XMLElementDecl element = new XMLElementDecl();
-                fGrammar.getElementDecl(elementIndex, element);
-                System.out.println("element: "+fStringPool.toString(element.name.localpart));
-                System.out.println("attlistIndex " + attlistIndex + "\n"+
-                    "attName : '"+fStringPool.toString(fTempAttDecl.name.localpart) + "'\n"
-                                   + "attType : "+fTempAttDecl.type + "\n"
-                                   + "attDefaultType : "+fTempAttDecl.defaultType + "\n"
-                                   + "attDefaultValue : '"+fTempAttDecl.defaultValue + "'\n"
-                                   + attrList.getLength() +"\n"
-                                   );
-            }
-            /***/
-
-            int attPrefix = fTempAttDecl.name.prefix;
-            int attName = fTempAttDecl.name.rawname;
-            int attLocalpart = fTempAttDecl.name.localpart;
-            int attType = attributeTypeName(fTempAttDecl);
-            int attDefType =fTempAttDecl.defaultType;
-            int attValue = -1 ;
-            if (fTempAttDecl.defaultValue != null ) {
-                attValue = fStringPool.addSymbol(fTempAttDecl.defaultValue);
-            }
-            boolean specified = false;
-            boolean required = attDefType == XMLAttributeDecl.DEFAULT_TYPE_REQUIRED;
-
-
-            /****
-            if (fValidating && fGrammar != null && fGrammarIsDTDGrammar && attValue != -1) {
-                normalizeAttValue(null, fTempAttDecl.name,
-                                  attValue,attType,fTempAttDecl.list, 
-                                  fTempAttDecl.enumeration);
-            }
-            /****/
-
-            if (firstCheck != -1) {
-                boolean cdata = attType == fCDATASymbol;
-                if (!cdata || required || attValue != -1) {
-                    int i = attrList.getFirstAttr(firstCheck);
-                    while (i != -1 && (lastCheck == -1 || i <= lastCheck)) {
-
-                        if ( attrList.getAttrName(i) == fTempAttDecl.name.rawname ) {
-
-                            if (validationEnabled && attDefType == XMLAttributeDecl.DEFAULT_TYPE_FIXED) {
-                                int alistValue = attrList.getAttValue(i);
-                                if (alistValue != attValue &&
-                                    !fStringPool.toString(alistValue).equals(fStringPool.toString(attValue))) {
-                                    Object[] args = { fStringPool.toString(elementNameIndex),
-                                        fStringPool.toString(attName),
-                                        fStringPool.toString(alistValue),
-                                        fStringPool.toString(attValue)};
-                                    fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                                               XMLMessages.XML_DOMAIN,
-                                                               XMLMessages.MSG_FIXED_ATTVALUE_INVALID,
-                                                               XMLMessages.VC_FIXED_ATTRIBUTE_DEFAULT,
-                                                               args,
-                                                               XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                                }
-                            }
-                            specified = true;
-                            break;
-                        }
-                        i = attrList.getNextAttr(i);
-                    }
-                }
-            }
-
-            if (!specified) {
-                if (required) {
-                    if (validationEnabled) {
-                        Object[] args = { fStringPool.toString(elementNameIndex),
-                            fStringPool.toString(attName)};
-                        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                                   XMLMessages.XML_DOMAIN,
-                                                   XMLMessages.MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED,
-                                                   XMLMessages.VC_REQUIRED_ATTRIBUTE,
-                                                   args,
-                                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                    }
-                } else if (attValue != -1) {
-                    if (validationEnabled && standalone )
-                        if ( fGrammarIsDTDGrammar 
-                             && ((DTDGrammar) fGrammar).getAttributeDeclIsExternal(attlistIndex) ) {
-
-                            Object[] args = { fStringPool.toString(elementNameIndex),
-                                fStringPool.toString(attName)};
-                            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                                       XMLMessages.XML_DOMAIN,
-                                                       XMLMessages.MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED,
-                                                       XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
-                                                       args,
-                                                       XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                        }
-                    if (attType == fIDREFSymbol) {
-                        this.fValIDRef.validate( fStringPool.toString(attValue), this.fStoreIDRef );
-                    } else if (attType == fIDREFSSymbol) {
-                        this.fValIDRefs.validate( fStringPool.toString(attValue), this.fStoreIDRef );
-                    }
-                    if (attrIndex == -1) {
-                        attrIndex = attrList.startAttrList();
-                    }
-
-                    fTempQName.setValues(attPrefix, attLocalpart, attName, fTempAttDecl.name.uri);
-                    int newAttr = attrList.addAttr(fTempQName, 
-                                                   attValue, attType, 
-                                                   false, false);
-                    if (lastCheck == -1) {
-                        lastCheck = newAttr;
-                    }
-                }
-            }
-            attlistIndex = fGrammar.getNextAttributeDeclIndex(attlistIndex);
-        }
-        return attrIndex;
-
-    } // addDTDDefaultAttributes(int,XMLAttrList,int,boolean,boolean):int
-
-    // content models
-
-    /** Queries the content model for the specified element index. */
-    private XMLContentModel getElementContentModel(int elementIndex) throws CMException {
-        XMLContentModel contentModel = null;
-        if ( elementIndex > -1) {
-            if ( fGrammar.getElementDecl(elementIndex,fTempElementDecl) ) {
-                contentModel = fGrammar.getElementContentModel(elementIndex);
-            }
-        }
-        //return fGrammar.getElementContentModel(elementIndex);
-        return contentModel;
-    }
-
-
-
-    // query attribute information
-
-    /** Returns an attribute definition for an element type. */
-    // this is only used by DTD validation.
-    private int getAttDef(QName element, QName attribute) {
-        if (fGrammar != null) {
-            int scope = fCurrentScope;
-            if (element.uri > -1) {
-                scope = TOP_LEVEL_SCOPE;
-            }
-            int elementIndex = fGrammar.getElementDeclIndex(element,scope);
-            if (elementIndex == -1) {
-                return -1;
-            }
-            int attDefIndex = fGrammar.getFirstAttributeDeclIndex(elementIndex);
-            while (attDefIndex != -1) {
-                fGrammar.getAttributeDecl(attDefIndex, fTempAttributeDecl);
-                if (fTempAttributeDecl.name.localpart == attribute.localpart &&
-                    fTempAttributeDecl.name.uri == attribute.uri ) {
-                    return attDefIndex;
-                }
-                attDefIndex = fGrammar.getNextAttributeDeclIndex(attDefIndex);
-            }
-        }
-        return -1;
-
-    } // getAttDef(QName,QName)
-
-    /** Returns an attribute definition for an element type. */
-    private int getAttDefByElementIndex(int elementIndex, QName attribute) {
-        if (fGrammar != null && elementIndex > -1) {
-            if (elementIndex == -1) {
-                return -1;
-            }
-            int attDefIndex = fGrammar.getFirstAttributeDeclIndex(elementIndex);
-            while (attDefIndex != -1) {
-                fGrammar.getAttributeDecl(attDefIndex, fTempAttDecl);
-
-                if (fGrammarIsDTDGrammar) {
-                    if (fTempAttDecl.name.rawname == attribute.rawname )
-                        return attDefIndex;
-                } else
-                    if (fTempAttDecl.name.localpart == attribute.localpart &&
-                        fTempAttDecl.name.uri == attribute.uri ) {
-                    return attDefIndex;
-                }
-
-                if (fGrammarIsSchemaGrammar) {
-                    if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_ANY) {
-                        return attDefIndex;
-                    } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LOCAL) {
-                        if (attribute.uri == -1) {
-                            return attDefIndex;
-                        }
-                    } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
-                        if (attribute.uri != fTempAttDecl.name.uri) {
-                            return attDefIndex;
-                        }
-                    } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LIST) {
-                        if (fStringPool.stringInList(fTempAttDecl.enumeration, attribute.uri)) {
-                            return attDefIndex;
-                        }
-                    }
-                }
-
-                attDefIndex = fGrammar.getNextAttributeDeclIndex(attDefIndex);
-            }
-        }
-        return -1;
-
-    } // getAttDef(QName,QName)
-
-    // validation
-
-    /** Root element specified. */
-    private void rootElementSpecified(QName rootElement) throws Exception {
-
-        // this is what it used to be
-        //if  (fDynamicValidation && !fSeenDoctypeDecl) {
-        //fValidating = false;
-        //}
-
-
-        if ( fLoadDTDGrammar )
-            // initialize the grammar to be the default one, 
-            // it definitely should be a DTD Grammar at this case;
-            if (fGrammar == null) {
-
-                fGrammar = fGrammarResolver.getGrammar("");
-
-                //TO DO, for ericye debug only
-                if (fGrammar == null && DEBUG_SCHEMA_VALIDATION) {
-                    System.out.println("Oops! no grammar is found for validation");
-                }
-
-                if (fDynamicValidation && fGrammar==null) {
-                    fValidating = false;
-                }
-
-                if (fGrammar != null) {
-                    if (fGrammar instanceof DTDGrammar) {
-                        fGrammarIsDTDGrammar = true;
-                        fGrammarIsSchemaGrammar = false;
-                    } else if ( fGrammar instanceof SchemaGrammar ) {
-                        fGrammarIsSchemaGrammar = true;
-                        fGrammarIsDTDGrammar = false;
-                    }
-
-                    fGrammarNameSpaceIndex = fEmptyURI;
-                }
-            }
-
-        if (fValidating) {
-            if ( fGrammarIsDTDGrammar && 
-                 ((DTDGrammar) fGrammar).getRootElementQName(fRootElement) ) {
-
-                String root1 = fStringPool.toString(fRootElement.rawname);
-                String root2 = fStringPool.toString(rootElement.rawname);
-                if (!root1.equals(root2)) {
-                    reportRecoverableXMLError(XMLMessages.MSG_ROOT_ELEMENT_TYPE,
-                                              XMLMessages.VC_ROOT_ELEMENT_TYPE,
-                                              fRootElement.rawname, 
-                                              rootElement.rawname);
-                }
-            }
-        }
-
-        if (fNamespacesEnabled) {
-            if (fNamespacesScope == null) {
-                fNamespacesScope = new NamespacesScope(this);
-                fNamespacesPrefix = fStringPool.addSymbol("xmlns");
-                fNamespacesScope.setNamespaceForPrefix(fNamespacesPrefix, -1);
-                int xmlSymbol = fStringPool.addSymbol("xml");
-                int xmlNamespace = fStringPool.addSymbol("http://www.w3.org/XML/1998/namespace");
-                fNamespacesScope.setNamespaceForPrefix(xmlSymbol, xmlNamespace);
-            }
-        }
-
-    } // rootElementSpecified(QName)
-
-    /** Switchs to correct validating symbol tables when Schema changes.*/
-
-    private boolean switchGrammar(int newGrammarNameSpaceIndex) throws Exception {
-        Grammar tempGrammar = fGrammarResolver.getGrammar(fStringPool.toString(newGrammarNameSpaceIndex));
-        if (tempGrammar == null) {
-            // This is a case where namespaces is on with a DTD grammar.
-            tempGrammar = fGrammarResolver.getGrammar("");
-        }
-        if (tempGrammar == null) {
-            return false;
-        } else {
-            fGrammar = tempGrammar;
-            if (fGrammar instanceof DTDGrammar) {
-                fGrammarIsDTDGrammar = true;
-                fGrammarIsSchemaGrammar = false;
-            } else if ( fGrammar instanceof SchemaGrammar ) {
-                fGrammarIsSchemaGrammar = true;
-                fGrammarIsDTDGrammar = false;
-            }
-
-            return true;
-        }
-    }
-
-    /** Binds namespaces to the element and attributes. */
-    private void bindNamespacesToElementAndAttributes(QName element, 
-                                                      XMLAttrList attrList)
-    throws Exception {
-
-        fNamespacesScope.increaseDepth();
-
-        //Vector schemaCandidateURIs = null;
-        Hashtable locationUriPairs = null;
-
-        if (fAttrListHandle != -1) {
-            int index = attrList.getFirstAttr(fAttrListHandle);
-            while (index != -1) {
-                int attName = attrList.getAttrName(index);
-                int attPrefix = attrList.getAttrPrefix(index);
-                if (fStringPool.equalNames(attName, fXMLLang)) {
-                    /***
-                    // NOTE: This check is done in the validateElementsAndAttributes
-                    //       method.
-                    fDocumentScanner.checkXMLLangAttributeValue(attrList.getAttValue(index));
-                    /***/
-                } else if (fStringPool.equalNames(attName, fNamespacesPrefix)) {
-                    int uri = fStringPool.addSymbol(attrList.getAttValue(index));
-                    fNamespacesScope.setNamespaceForPrefix(StringPool.EMPTY_STRING, uri);
-                } else {
-                    if (attPrefix == fNamespacesPrefix) {
-                        int nsPrefix = attrList.getAttrLocalpart(index);
-                        int uri = fStringPool.addSymbol(attrList.getAttValue(index));
-                        fNamespacesScope.setNamespaceForPrefix(nsPrefix, uri);
-
-                        if (fValidating && fSchemaValidation) {
-                            boolean seeXsi = false;
-                            String attrValue = fStringPool.toString(attrList.getAttValue(index));
-
-                            if (attrValue.equals(SchemaSymbols.URI_XSI)) {
-                                fXsiPrefix = nsPrefix;
-                                seeXsi = true;
-                            }
-
-                            if (!seeXsi) {
-                                /***
-                                if (schemaCandidateURIs == null) {
-                                    schemaCandidateURIs = new Vector();
-                                }
-                                schemaCandidateURIs.addElement( fStringPool.toString(uri) );
-                                /***/
-                            }
-                        }
-                    }
-                }
-                index = attrList.getNextAttr(index);
-            }
-            // if validating, walk through the list again to deal with "xsi:...."
-            if (fValidating && fSchemaValidation) {
-                fXsiTypeAttValue = -1;
-                index = attrList.getFirstAttr(fAttrListHandle);
-                while (index != -1) {
-
-                    int attName = attrList.getAttrName(index);
-                    int attPrefix = attrList.getAttrPrefix(index);
-
-                    if (fStringPool.equalNames(attName, fNamespacesPrefix)) {
-                        // REVISIT
-                    } else {
-                        if ( DEBUG_SCHEMA_VALIDATION ) {
-                            System.out.println("deal with XSI");
-                            System.out.println("before find XSI: "+fStringPool.toString(attPrefix)
-                                               +","+fStringPool.toString(fXsiPrefix) );
-                        }
-                        if ( fXsiPrefix != -1 && attPrefix == fXsiPrefix ) {
-
-                            if (DEBUG_SCHEMA_VALIDATION) {
-                                System.out.println("find XSI: "+fStringPool.toString(attPrefix)
-                                                   +","+fStringPool.toString(attName) );
-                            }
-
-
-                            int localpart = attrList.getAttrLocalpart(index);
-                            if (localpart == fStringPool.addSymbol(SchemaSymbols.XSI_SCHEMALOCACTION)) {
-                                if (locationUriPairs == null) {
-                                    locationUriPairs = new Hashtable();
-                                }
-                                parseSchemaLocation(fStringPool.toString(attrList.getAttValue(index)), locationUriPairs);
-                            } else if (localpart == fStringPool.addSymbol(SchemaSymbols.XSI_NONAMESPACESCHEMALOCACTION)) {
-                                if (locationUriPairs == null) {
-                                    locationUriPairs = new Hashtable();
-                                }
-                                locationUriPairs.put(fStringPool.toString(attrList.getAttValue(index)), "");
-                                if (fNamespacesScope != null) {
-                                    //bind prefix "" to URI "" in this case
-                                    fNamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(""), 
-                                                                            fStringPool.addSymbol(""));
-                                }
-                            } else if (localpart == fStringPool.addSymbol(SchemaSymbols.XSI_TYPE)) {
-                                fXsiTypeAttValue = attrList.getAttValue(index);
-                            }
-                            // REVISIT: should we break here? 
-                            //break;
-                        }
-                    }
-                    index = attrList.getNextAttr(index);
-                }
-
-                // try to resolve all the grammars here
-                if (locationUriPairs != null) {
-                    Enumeration locations = locationUriPairs.keys();
-
-                    while (locations.hasMoreElements()) {
-                        String loc = (String) locations.nextElement();
-                        String uri = (String) locationUriPairs.get(loc);
-                        resolveSchemaGrammar( loc, uri);
-                        //schemaCandidateURIs.removeElement(uri);
-                    }
-                }
-
-                //TO DO: This should be a feature that can be turned on or off
-                /*****
-                for (int i=0; i< schemaCandidateURIs.size(); i++) {
-                
-                    String uri = (String) schemaCandidateURIs.elementAt(i);
-                    resolveSchemaGrammar(uri);
-                }
-                /*****/
-
-            }
-
-        }
-
-        // bind element to URI
-        int prefix = element.prefix != -1 ? element.prefix : 0;
-        int uri    = fNamespacesScope.getNamespaceForPrefix(prefix);
-        if (element.prefix != -1 || uri != -1) {
-            element.uri = uri;
-            if (element.uri == -1) {
-                Object[] args = { fStringPool.toString(element.prefix)};
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           XMLMessages.XMLNS_DOMAIN,
-                                           XMLMessages.MSG_PREFIX_DECLARED,
-                                           XMLMessages.NC_PREFIX_DECLARED,
-                                           args,
-                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-            }
-        }
-
-
-        if (fAttrListHandle != -1) {
-            int index = attrList.getFirstAttr(fAttrListHandle);
-            while (index != -1) {
-                int attName = attrList.getAttrName(index);
-                if (!fStringPool.equalNames(attName, fNamespacesPrefix)) {
-                    int attPrefix = attrList.getAttrPrefix(index);
-                    if (attPrefix != fNamespacesPrefix) {
-                        if (attPrefix != -1 ) {
-                            int attrUri = fNamespacesScope.getNamespaceForPrefix(attPrefix);
-                            if (attrUri == -1) {
-                                Object[] args = { fStringPool.toString(attPrefix)};
-                                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                                           XMLMessages.XMLNS_DOMAIN,
-                                                           XMLMessages.MSG_PREFIX_DECLARED,
-                                                           XMLMessages.NC_PREFIX_DECLARED,
-                                                           args,
-                                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                            }
-                            attrList.setAttrURI(index, attrUri);
-                        }
-                    }
-                }
-                index = attrList.getNextAttr(index);
-            }
-        }
-
-    } // bindNamespacesToElementAndAttributes(QName,XMLAttrList)
-
-    void parseSchemaLocation(String schemaLocationStr, Hashtable locationUriPairs){
-        if (locationUriPairs != null) {
-            StringTokenizer tokenizer = new StringTokenizer(schemaLocationStr, " \n\t\r", false);
-            int tokenTotal = tokenizer.countTokens();
-            if (tokenTotal % 2 != 0 ) {
-                // TO DO: report warning - malformed schemaLocation string
-            } else {
-                while (tokenizer.hasMoreTokens()) {
-                    String uri = tokenizer.nextToken();
-                    String location = tokenizer.nextToken();
-
-                    locationUriPairs.put(location, uri);
-                }
-            }
-        } else {
-            // TO DO: should report internal error here
-        }
-
-    }// parseSchemaLocaltion(String, Hashtable)
-    private void resolveSchemaGrammar( String loc, String uri) throws Exception {
-
-        SchemaGrammar grammar = (SchemaGrammar) fGrammarResolver.getGrammar(uri);
-
-        if (grammar == null) {
-            DOMParser parser = new DOMParser();
-            parser.setEntityResolver( new Resolver(fEntityHandler) );
-            parser.setErrorHandler(  new ErrorHandler() );
-
-            try {
-                parser.setFeature("http://xml.org/sax/features/validation", false);
-                parser.setFeature("http://xml.org/sax/features/namespaces", true);
-                parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
-            } catch (  org.xml.sax.SAXNotRecognizedException e ) {
-                e.printStackTrace();
-            } catch ( org.xml.sax.SAXNotSupportedException e ) {
-                e.printStackTrace();
-            }
-
-            // expand it before passing it to the parser
-            InputSource source = null;
-            EntityResolver currentER = parser.getEntityResolver();
-            if (currentER != null) {
-                source = currentER.resolveEntity("", loc);
-            }
-            if (source == null) {
-                loc = fEntityHandler.expandSystemId(loc);
-                source = new InputSource(loc);
-            }
-            try {
-                parser.parse( source );
-            } catch ( IOException e ) {
-                e.printStackTrace();
-            } catch ( SAXException e ) {
-                //System.out.println("loc = "+loc);
-                //e.printStackTrace();
-                reportRecoverableXMLError( XMLMessages.MSG_GENERIC_SCHEMA_ERROR, 
-                                           XMLMessages.SCHEMA_GENERIC_ERROR, e.getMessage() );
-            }
-
-            Document     document   = parser.getDocument(); //Our Grammar
-
-            TraverseSchema tst = null;
-            try {
-                if (DEBUG_SCHEMA_VALIDATION) {
-                    System.out.println("I am geting the Schema Document");
-                }
-
-                Element root   = document.getDocumentElement();// This is what we pass to TraverserSchema
-                if (root == null) {
-                    reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR, "Can't get back Schema document's root element :" + loc); 
-                } else {
-                    if (uri == null || !uri.equals(root.getAttribute(SchemaSymbols.ATT_TARGETNAMESPACE)) ) {
-                        reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR, "Schema in " + loc + " has a different target namespace " + 
-                                                  "from the one specified in the instance document :" + uri); 
-                    }
-                    grammar = new SchemaGrammar();
-                    grammar.setGrammarDocument(document);
-                    tst = new TraverseSchema( root, fStringPool, (SchemaGrammar)grammar, fGrammarResolver, fErrorReporter, source.getSystemId());
-                    fGrammarResolver.putGrammar(document.getDocumentElement().getAttribute("targetNamespace"), grammar);
-                }
-            } catch (Exception e) {
-                e.printStackTrace(System.err);
-            }
-        }
-
-    }
-
-    private void resolveSchemaGrammar(String uri) throws Exception{
-
-        resolveSchemaGrammar(uri, uri);
-
-    }
-
-    static class Resolver implements EntityResolver {
-
-        //
-        // Constants
-        //
-
-        private static final String SYSTEM[] = {
-            "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/structures.dtd",
-            "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/datatypes.dtd",
-            "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/versionInfo.ent",
-        };
-        private static final String PATH[] = {
-            "structures.dtd",
-            "datatypes.dtd",
-            "versionInfo.ent",
-        };
-
-        //
-        // Data
-        //
-
-        private DefaultEntityHandler fEntityHandler;
-
-        //
-        // Constructors
-        //
-
-        public Resolver(DefaultEntityHandler handler) {
-            fEntityHandler = handler;
-        }
-
-        //
-        // EntityResolver methods
-        //
-
-        public InputSource resolveEntity(String publicId, String systemId)
-        throws IOException, SAXException {
-
-            // looking for the schema DTDs?
-            for (int i = 0; i < SYSTEM.length; i++) {
-                if (systemId.equals(SYSTEM[i])) {
-                    InputSource source = new InputSource(getClass().getResourceAsStream(PATH[i]));
-                    source.setPublicId(publicId);
-                    source.setSystemId(systemId);
-                    return source;
-                }
-            }
-
-            // first try to resolve using user's entity resolver
-            EntityResolver resolver = fEntityHandler.getEntityResolver();
-            if (resolver != null) {
-                InputSource source = resolver.resolveEntity(publicId, systemId);
-                if (source != null) {
-                    return source;
-                }
-            }
-
-            // use default resolution
-            return new InputSource(fEntityHandler.expandSystemId(systemId));
-
-        } // resolveEntity(String,String):InputSource
-
-    } // class Resolver
-
-    static class ErrorHandler implements org.xml.sax.ErrorHandler {
-
-        /** Warning. */
-        public void warning(SAXParseException ex) {
-            System.err.println("[Warning] "+
-                               getLocationString(ex)+": "+
-                               ex.getMessage());
-        }
-
-        /** Error. */
-        public void error(SAXParseException ex) {
-            System.err.println("[Error] "+
-                               getLocationString(ex)+": "+
-                               ex.getMessage());
-        }
-
-        /** Fatal error. */
-        public void fatalError(SAXParseException ex)  {
-            System.err.println("[Fatal Error] "+
-                               getLocationString(ex)+": "+
-                               ex.getMessage());
-            //throw ex;
-        }
-
-        //
-        // Private methods
-        //
-
-        /** Returns a string of the location. */
-        private String getLocationString(SAXParseException ex) {
-            StringBuffer str = new StringBuffer();
-
-            String systemId_ = ex.getSystemId();
-            if (systemId_ != null) {
-                int index = systemId_.lastIndexOf('/');
-                if (index != -1)
-                    systemId_ = systemId_.substring(index + 1);
-                str.append(systemId_);
-            }
-            str.append(':');
-            str.append(ex.getLineNumber());
-            str.append(':');
-            str.append(ex.getColumnNumber());
-
-            return str.toString();
-
-        } // getLocationString(SAXParseException):String
-    }
-
-    private int attributeTypeName(XMLAttributeDecl attrDecl) {
-        switch (attrDecl.type) {
-        case XMLAttributeDecl.TYPE_ENTITY: {
-                return attrDecl.list ? fENTITIESSymbol : fENTITYSymbol;
-            }
-        case XMLAttributeDecl.TYPE_ENUMERATION: {
-                String enumeration = fStringPool.stringListAsString(attrDecl.enumeration);
-                return fStringPool.addString(enumeration);
-            }
-        case XMLAttributeDecl.TYPE_ID: {
-                return fIDSymbol;
-            }
-        case XMLAttributeDecl.TYPE_IDREF: {
-                return attrDecl.list ? fIDREFSSymbol : fIDREFSymbol;
-            }
-        case XMLAttributeDecl.TYPE_NMTOKEN: {
-                return attrDecl.list ? fNMTOKENSSymbol : fNMTOKENSSymbol;
-            }
-        case XMLAttributeDecl.TYPE_NOTATION: {
-                return fNOTATIONSymbol;
-            }
-        }
-        return fCDATASymbol;
-    }
-
-    /** Validates element and attributes. */
-    private void validateElementAndAttributes(QName element, 
-                                              XMLAttrList attrList) 
-        throws Exception {
-
-        if ((fElementDepth >= 0 && fValidationFlagStack[fElementDepth] != 0 )|| 
-            (fGrammar == null && !fValidating && !fNamespacesEnabled) ) {
-            fCurrentElementIndex = -1;
-            fCurrentContentSpecType = -1;
-            fInElementContent = false;
-            if (fAttrListHandle != -1) {
-                fAttrList.endAttrList();
-                int index = fAttrList.getFirstAttr(fAttrListHandle);
-                while (index != -1) {
-                    if (fStringPool.equalNames(fAttrList.getAttrName(index), fXMLLang)) {
-                        fDocumentScanner.checkXMLLangAttributeValue(fAttrList.getAttValue(index));
-                        break;
-                    }
-                    index = fAttrList.getNextAttr(index);
-                }
-            }
-            return;
-        }
-
-        int elementIndex = -1;
-        int contentSpecType = -1;
-
-        boolean skipThisOne = false;
-        boolean laxThisOne = false;
-
-        if ( fGrammarIsSchemaGrammar && fContentLeafStack[fElementDepth] != null ) {
-            ContentLeafNameTypeVector cv = fContentLeafStack[fElementDepth];
-
-            QName[] fElemMap = cv.leafNames;
-            for (int i=0; i<cv.leafCount; i++) {
-                int type = cv.leafTypes[i]  ;
-                //System.out.println("******* see a ANY_OTHER_SKIP, "+type+","+element+","+fElemMap[i]+"\n*******");
-
-                if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
-                    if (fElemMap[i].uri==element.uri
-                        && fElemMap[i].localpart == element.localpart)
-                        break;
-                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
-                    int uri = fElemMap[i].uri;
-                    if (uri == -1 || uri == element.uri) {
-                        break;
-                    }
-                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
-                    if (element.uri == -1) {
-                        break;
-                    }
-                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
-                    if (fElemMap[i].uri != element.uri) {
-                        break;
-                    }
-                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_SKIP) {
-                    int uri = fElemMap[i].uri;
-                    if (uri == -1 || uri == element.uri) {
-                        skipThisOne = true;
-                        break;
-                    }
-                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL_SKIP) {
-                    if (element.uri == -1) {
-                        skipThisOne = true;
-                        break;
-                    }
-                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_SKIP) {
-                    if (fElemMap[i].uri != element.uri) {
-                        skipThisOne = true;
-                        break;
-                    }
-                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LAX) {
-                    int uri = fElemMap[i].uri;
-                    if (uri == -1 || uri == element.uri) {
-                        laxThisOne = true;
-                        break;
-                    }
-                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL_LAX) {
-                    if (element.uri == -1) {
-                        laxThisOne = true;
-                        break;
-                    }
-                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_LAX) {
-                    if (fElemMap[i].uri != element.uri) {
-                        laxThisOne = true;
-                        break;
-                    }
-                }
-
-            }
-
-        }
-
-        if (skipThisOne) {
-            fNeedValidationOff = true;
-        } else {
-
-            //REVISIT: is this the right place to check on if the Schema has changed?
-
-            if ( fNamespacesEnabled && fValidating && element.uri != fGrammarNameSpaceIndex && element.uri != -1  ) {
-                fGrammarNameSpaceIndex = element.uri;
-
-                boolean success = switchGrammar(fGrammarNameSpaceIndex);
-
-                if (!success && !laxThisOne) {
-                    reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR, 
-                                              "Grammar with uri : " + fStringPool.toString(fGrammarNameSpaceIndex) 
-                                              + " , can not found");
-                }
-            }
-
-
-            if ( fGrammar != null ) {
-                if (DEBUG_SCHEMA_VALIDATION) {
-                    System.out.println("*******Lookup element: uri: " + fStringPool.toString(element.uri)+
-                                       "localpart: '" + fStringPool.toString(element.localpart)
-                                       +"' and scope : " + fCurrentScope+"\n");
-                }
-
-                elementIndex = fGrammar.getElementDeclIndex(element,fCurrentScope);
-
-                if (elementIndex == -1 ) {
-                    elementIndex = fGrammar.getElementDeclIndex(element, TOP_LEVEL_SCOPE);
-                }
-
-                if (elementIndex == -1) {
-                    // if validating based on a Schema, try to resolve the element again by look it up in its ancestor types
-                    if (fGrammarIsSchemaGrammar && fCurrentElementIndex != -1) {
-                        TraverseSchema.ComplexTypeInfo baseTypeInfo = null;
-                        baseTypeInfo = ((SchemaGrammar)fGrammar).getElementComplexTypeInfo(fCurrentElementIndex);
-                        //TO DO: 
-                        //      should check if baseTypeInfo is from the same Schema.
-                        while (baseTypeInfo != null) {
-                            elementIndex = fGrammar.getElementDeclIndex(element, baseTypeInfo.scopeDefined);
-                            if (elementIndex > -1 ) {
-                                break;
-                            }
-                            baseTypeInfo = baseTypeInfo.baseComplexTypeInfo;
-                        }
-                    }
-                    //if still can't resolve it, try TOP_LEVEL_SCOPE AGAIN
-                    /****
-                    if ( element.uri == -1 && elementIndex == -1 
-                    && fNamespacesScope != null 
-                    && fNamespacesScope.getNamespaceForPrefix(StringPool.EMPTY_STRING) != -1 ) {
-                    elementIndex = fGrammar.getElementDeclIndex(element.localpart, TOP_LEVEL_SCOPE);
-                    // REVISIT:
-                    // this is a hack to handle the situation where namespace prefix "" is bound to nothing, and there
-                    // is a "noNamespaceSchemaLocation" specified, and element 
-                    element.uri = StringPool.EMPTY_STRING;
-                    }
-                    /****/
-
-                    /****/
-                    if (elementIndex == -1) {
-                        if (laxThisOne) {
-                            fNeedValidationOff = true;
-                        } else
-                            if (DEBUG_SCHEMA_VALIDATION)
-                            System.out.println("!!! can not find elementDecl in the grammar, " +
-                                               " the element localpart: " + element.localpart +
-                                               "["+fStringPool.toString(element.localpart) +"]" +
-                                               " the element uri: " + element.uri + 
-                                               "["+fStringPool.toString(element.uri) +"]" +
-                                               " and the current enclosing scope: " + fCurrentScope );
-                    }
-                    /****/
-                }
-
-                if (DEBUG_SCHEMA_VALIDATION) {
-                    fGrammar.getElementDecl(elementIndex, fTempElementDecl);
-                    System.out.println("elementIndex: " + elementIndex+" \n and itsName : '" 
-                                       + fStringPool.toString(fTempElementDecl.name.localpart)
-                                       +"' \n its ContentType:" + fTempElementDecl.type
-                                       +"\n its ContentSpecIndex : " + fTempElementDecl.contentSpecIndex +"\n"+
-                                       " and the current enclosing scope: " + fCurrentScope);
-                }
-            }
-
-            contentSpecType =  getContentSpecType(elementIndex);
-
-            if (fGrammarIsSchemaGrammar && elementIndex != -1) {
-
-                // handle "xsi:type" right here
-                if (fXsiTypeAttValue > -1) {
-                    String xsiType = fStringPool.toString(fXsiTypeAttValue);
-                    int colonP = xsiType.indexOf(":");
-                    String prefix = "";
-                    String localpart = xsiType;
-                    if (colonP > -1) {
-                        prefix = xsiType.substring(0,colonP);
-                        localpart = xsiType.substring(colonP+1);
-                    }
-
-                    String uri = "";
-                    int uriIndex = -1;
-                    if (fNamespacesScope != null) {
-                        uriIndex = fNamespacesScope.getNamespaceForPrefix(fStringPool.addSymbol(prefix));
-                        if (uriIndex > -1) {
-                            uri = fStringPool.toString(uriIndex);
-                            if (uriIndex != fGrammarNameSpaceIndex) {
-                                fGrammarNameSpaceIndex = fCurrentSchemaURI = uriIndex;
-                                boolean success = switchGrammar(fCurrentSchemaURI);
-                                if (!success && !fNeedValidationOff) {
-                                    reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, 
-                                                              XMLMessages.SCHEMA_GENERIC_ERROR, 
-                                                              "Grammar with uri : " 
-                                                              + fStringPool.toString(fCurrentSchemaURI) 
-                                                              + " , can not found");
-                                }
-                            }
-                        }
-                    }
-
-
-                    Hashtable complexRegistry = ((SchemaGrammar)fGrammar).getComplexTypeRegistry();
-                    DatatypeValidatorFactoryImpl dataTypeReg = ((SchemaGrammar)fGrammar).getDatatypeRegistry();
-                    if (complexRegistry==null || dataTypeReg == null) {
-                        reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, 
-                                                  XMLMessages.SCHEMA_GENERIC_ERROR, 
-                                                  fErrorReporter.getLocator().getSystemId()
-                                                  +" line"+fErrorReporter.getLocator().getLineNumber()
-                                                  +", canot resolve xsi:type = " + xsiType+"  ---2");
-                    } else {
-                        TraverseSchema.ComplexTypeInfo typeInfo = 
-                        (TraverseSchema.ComplexTypeInfo) complexRegistry.get(uri+","+localpart);
-                        //TO DO:
-                        //      here need to check if this substitution is legal based on the current active grammar,
-                        //      this should be easy, cause we already saved final, block and base type information in 
-                        //      the SchemaGrammar.
-
-                        if (typeInfo==null) {
-                            if (uri.length() == 0 || uri.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) ) {
-                                fXsiTypeValidator = dataTypeReg.getDatatypeValidator(localpart);
-                            } else
-                                fXsiTypeValidator = dataTypeReg.getDatatypeValidator(uri+","+localpart);
-                            if ( fXsiTypeValidator == null )
-                                reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, 
-                                                          XMLMessages.SCHEMA_GENERIC_ERROR, 
-                                                          "unresolved type : "+uri+","+localpart 
-                                                          +" found  in xsi:type handling");
-                        } else
-                            elementIndex = typeInfo.templateElementIndex;
-                    }
-
-                    fXsiTypeAttValue = -1;
-                }
-
-                //Change the current scope to be the one defined by this element.
-                fCurrentScope = ((SchemaGrammar) fGrammar).getElementDefinedScope(elementIndex);
-
-                //       here need to check if we need to switch Grammar by asking SchemaGrammar whether 
-                //       this element actually is of a type in another Schema.
-                String anotherSchemaURI = ((SchemaGrammar)fGrammar).getElementFromAnotherSchemaURI(elementIndex);
-                if (anotherSchemaURI != null) {
-                    //before switch Grammar, set the elementIndex to be the template elementIndex of its type
-                    if (contentSpecType != -1 
-                        && contentSpecType != XMLElementDecl.TYPE_EMPTY ) {
-                        TraverseSchema.ComplexTypeInfo typeInfo = ((SchemaGrammar) fGrammar).getElementComplexTypeInfo(elementIndex);
-                        if (typeInfo != null) {
-                            elementIndex = typeInfo.templateElementIndex;
-                        }
-
-                    }
-
-                    // now switch the grammar
-                    fGrammarNameSpaceIndex = fCurrentSchemaURI = fStringPool.addSymbol(anotherSchemaURI);
-                    boolean success = switchGrammar(fCurrentSchemaURI);
-                    if (!success && !fNeedValidationOff) {
-                        reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, 
-                                                  XMLMessages.SCHEMA_GENERIC_ERROR, 
-                                                  "Grammar with uri : " 
-                                                  + fStringPool.toString(fCurrentSchemaURI) 
-                                                  + " , can not found");
-                    }
-                }
-
-            }
-
-            if (contentSpecType == -1 && fValidating && !fNeedValidationOff ) {
-                reportRecoverableXMLError(XMLMessages.MSG_ELEMENT_NOT_DECLARED,
-                                          XMLMessages.VC_ELEMENT_VALID,
-                                          element.rawname);
-            }
-            if (fGrammar != null && fGrammarIsSchemaGrammar && elementIndex != -1) {
-                fAttrListHandle = addDefaultAttributes(elementIndex, attrList, fAttrListHandle, fValidating, fStandaloneReader != -1);
-            }
-            if (fAttrListHandle != -1) {
-                fAttrList.endAttrList();
-            }
-
-            if (DEBUG_PRINT_ATTRIBUTES) {
-                String elementStr = fStringPool.toString(element.rawname);
-                System.out.print("startElement: <" + elementStr);
-                if (fAttrListHandle != -1) {
-                    int index = attrList.getFirstAttr(fAttrListHandle);
-                    while (index != -1) {
-                        System.out.print(" " + fStringPool.toString(attrList.getAttrName(index)) + "=\"" +
-                                         fStringPool.toString(attrList.getAttValue(index)) + "\"");
-                        index = attrList.getNextAttr(index);
-                    }
-                }
-                System.out.println(">");
-            }
-            // REVISIT: Validation. Do we need to recheck for the xml:lang
-            //          attribute? It was already checked above -- perhaps
-            //          this is to check values that are defaulted in? If
-            //          so, this check could move to the attribute decl
-            //          callback so we can check the default value before
-            //          it is used.
-            if (fAttrListHandle != -1 && !fNeedValidationOff ) {
-                int index = fAttrList.getFirstAttr(fAttrListHandle);
-                while (index != -1) {
-                    int attrNameIndex = attrList.getAttrName(index);
-
-                    if (fStringPool.equalNames(attrNameIndex, fXMLLang)) {
-                        fDocumentScanner.checkXMLLangAttributeValue(attrList.getAttValue(index));
-                        // break;
-                    }
-                    // here, we validate every "user-defined" attributes
-                    int _xmlns = fStringPool.addSymbol("xmlns");
-
-                    if (attrNameIndex != _xmlns && attrList.getAttrPrefix(index) != _xmlns)
-                        if (fGrammar != null) {
-                            fAttrNameLocator = getLocatorImpl(fAttrNameLocator);
-                            fTempQName.setValues(attrList.getAttrPrefix(index), 
-                                                 attrList.getAttrLocalpart(index),
-                                                 attrList.getAttrName(index),
-                                                 attrList.getAttrURI(index) );
-                            int attDefIndex = getAttDefByElementIndex(elementIndex, fTempQName);
-
-                            if (fTempQName.uri != fXsiURI)
-                                if (attDefIndex == -1 ) {
-                                    if (fValidating) {
-                                        // REVISIT - cache the elem/attr tuple so that we only give
-                                        //  this error once for each unique occurrence
-                                        Object[] args = { fStringPool.toString(element.rawname),
-                                            fStringPool.toString(attrList.getAttrName(index))};
-
-                                        /*****/
-                                        fErrorReporter.reportError(fAttrNameLocator,
-                                                                   XMLMessages.XML_DOMAIN,
-                                                                   XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
-                                                                   XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
-                                                                   args,
-                                                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);   
-                                        /******/
-                                    }
-                                } else {
-
-                                    fGrammar.getAttributeDecl(attDefIndex, fTempAttDecl); 
-
-                                    int attributeType = attributeTypeName(fTempAttDecl);
-                                    attrList.setAttType(index, attributeType);
-
-                                    if (fValidating) {
-
-                                        if (fGrammarIsDTDGrammar && 
-                                            (fTempAttDecl.type == XMLAttributeDecl.TYPE_ENTITY ||
-                                             fTempAttDecl.type == XMLAttributeDecl.TYPE_ENUMERATION ||
-                                             fTempAttDecl.type == XMLAttributeDecl.TYPE_ID ||
-                                             fTempAttDecl.type == XMLAttributeDecl.TYPE_IDREF ||
-                                             fTempAttDecl.type == XMLAttributeDecl.TYPE_NMTOKEN ||
-                                             fTempAttDecl.type == XMLAttributeDecl.TYPE_NOTATION)
-                                           ) {
-                                            validateDTDattribute(element, attrList.getAttValue(index), fTempAttDecl);
-                                        }
-
-                                        // check to see if this attribute matched an attribute wildcard
-                                        else if ( fGrammarIsSchemaGrammar && 
-                                                  (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_ANY 
-                                                   ||fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LIST
-                                                   ||fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LOCAL 
-                                                   ||fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_OTHER) ) {
-
-                                            if (fTempAttDecl.defaultType == XMLAttributeDecl.PROCESSCONTENTS_SKIP) {
-                                                // attribute should just be bypassed, 
-                                            } else if ( fTempAttDecl.defaultType == XMLAttributeDecl.PROCESSCONTENTS_STRICT
-                                                        || fTempAttDecl.defaultType == XMLAttributeDecl.PROCESSCONTENTS_LAX) {
-
-                                                boolean reportError = false;
-                                                boolean processContentStrict = 
-                                                fTempAttDecl.defaultType == XMLAttributeDecl.PROCESSCONTENTS_STRICT;
-
-                                                if (fTempQName.uri == -1) {
-                                                    if (processContentStrict) {
-                                                        reportError = true;
-                                                    }
-                                                } else {
-                                                    Grammar aGrammar = 
-                                                    fGrammarResolver.getGrammar(fStringPool.toString(fTempQName.uri));
-
-                                                    if (aGrammar == null || !(aGrammar instanceof SchemaGrammar) ) {
-                                                        if (processContentStrict) {
-                                                            reportError = true;
-                                                        }
-                                                    } else {
-                                                        SchemaGrammar sGrammar = (SchemaGrammar) aGrammar;
-                                                        Hashtable attRegistry = sGrammar.getAttirubteDeclRegistry();
-                                                        if (attRegistry == null) {
-                                                            if (processContentStrict) {
-                                                                reportError = true;
-                                                            }
-                                                        } else {
-                                                            XMLAttributeDecl attDecl = (XMLAttributeDecl) attRegistry.get(fStringPool.toString(fTempQName.localpart));
-                                                            if (attDecl == null) {
-                                                                if (processContentStrict) {
-                                                                    reportError = true;
-                                                                }
-                                                            } else {
-                                                                DatatypeValidator attDV = attDecl.datatypeValidator;
-                                                                if (attDV == null) {
-                                                                    if (processContentStrict) {
-                                                                        reportError = true;
-                                                                    }
-                                                                } else {
-                                                                    try {
-                                                                        String  unTrimValue = fStringPool.toString(attrList.getAttValue(index));
-                                                                        String  value       = unTrimValue.trim();
-                                                                        if (attDecl.type == XMLAttributeDecl.TYPE_ID ) {
-                                                                            this.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
-                                                                        }
-                                                                        if (attDecl.type == XMLAttributeDecl.TYPE_IDREF ) {
-                                                                            attDV.validate(value, this.fStoreIDRef );
-                                                                        } else
-                                                                            attDV.validate(unTrimValue, null );
-                                                                    } catch (InvalidDatatypeValueException idve) {
-                                                                        fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                                                                                   SchemaMessageProvider.SCHEMA_DOMAIN,
-                                                                                                   SchemaMessageProvider.DatatypeError,
-                                                                                                   SchemaMessageProvider.MSG_NONE,
-                                                                                                   new Object [] { idve.getMessage()},
-                                                                                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                                                                    }
-                                                                }
-                                                            }
-                                                        }
-                                                    }
-                                                }
-                                                if (reportError) {
-                                                    Object[] args = { fStringPool.toString(element.rawname),
-                                                        "ANY---"+fStringPool.toString(attrList.getAttrName(index))};
-
-                                                    fErrorReporter.reportError(fAttrNameLocator,    
-                                                                               XMLMessages.XML_DOMAIN,
-                                                                               XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
-                                                                               XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
-                                                                               args,
-                                                                               XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-
-                                                }
-                                            }
-                                        } else if (fTempAttDecl.datatypeValidator == null) {
-                                            Object[] args = { fStringPool.toString(element.rawname),
-                                                fStringPool.toString(attrList.getAttrName(index))};
-
-                                            System.out.println("[Error] Datatypevalidator for attribute " + fStringPool.toString(attrList.getAttrName(index))
-                                                               + " not found in element type " + fStringPool.toString(element.rawname));
-                                            //REVISIT : is this the right message?
-                                            /****/
-                                            fErrorReporter.reportError(fAttrNameLocator,    
-                                                                       XMLMessages.XML_DOMAIN,
-                                                                       XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
-                                                                       XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
-                                                                       args,
-                                                                       XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);   
-                                            /****/
-                                        } else {
-                                            try {
-                                                String  unTrimValue = fStringPool.toString(attrList.getAttValue(index));
-                                                String  value       = unTrimValue.trim();
-                                                if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ID ) {
-                                                    this.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
-                                                } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_IDREF ) {
-                                                    fTempAttDecl.datatypeValidator.validate(value, this.fStoreIDRef );
-                                                } else {
-                                                    fTempAttDecl.datatypeValidator.validate(unTrimValue, null );
-                                                }
-
-                                            } catch (InvalidDatatypeValueException idve) {
-                                                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                                                           SchemaMessageProvider.SCHEMA_DOMAIN,
-                                                                           SchemaMessageProvider.DatatypeError,
-                                                                           SchemaMessageProvider.MSG_NONE,
-                                                                           new Object [] { idve.getMessage()},
-                                                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                                            }
-                                        }
-                                    } // end of if (fValidating)
-
-
-                                } // end of if (attDefIndex == -1) else
-
-                        }// end of if (fGrammar != null)
-                    index = fAttrList.getNextAttr(index);
-                }
-            }
-        }
-        if (fAttrListHandle != -1) {
-            int index = attrList.getFirstAttr(fAttrListHandle);
-            while (index != -1) {
-                int attName = attrList.getAttrName(index);
-                if (!fStringPool.equalNames(attName, fNamespacesPrefix)) {
-                    int attPrefix = attrList.getAttrPrefix(index);
-                    if (attPrefix != fNamespacesPrefix) {
-                        if (attPrefix != -1) {
-                            int uri = fNamespacesScope.getNamespaceForPrefix(attPrefix);
-                            if (uri == -1) {
-                                Object[] args = { fStringPool.toString(attPrefix)};
-                                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                                           XMLMessages.XMLNS_DOMAIN,
-                                                           XMLMessages.MSG_PREFIX_DECLARED,
-                                                           XMLMessages.NC_PREFIX_DECLARED,
-                                                           args,
-                                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                            }
-                            attrList.setAttrURI(index, uri);
-                        }
-                    }
-                }
-                index = attrList.getNextAttr(index);
-            }
-        }
-
-        fCurrentElementIndex = elementIndex;
-        fCurrentContentSpecType = contentSpecType;
-
-        if (fValidating && contentSpecType == XMLElementDecl.TYPE_SIMPLE) {
-            fBufferDatatype = true;
-            fDatatypeBuffer.setLength(0);
-        }
-
-        fInElementContent = (contentSpecType == XMLElementDecl.TYPE_CHILDREN);
-
-    } // validateElementAndAttributes(QName,XMLAttrList)
-
-
-    //validate attributes in DTD fashion
-    private void validateDTDattribute(QName element, int attValue, 
-                                      XMLAttributeDecl attributeDecl) throws Exception{
-        AttributeValidator av = null;
-        switch (attributeDecl.type) {
-        case XMLAttributeDecl.TYPE_ENTITY:
-            {
-                boolean isAlistAttribute = attributeDecl.list;//Caveat - Save this information because invalidStandaloneAttDef
-                String  unTrimValue      = fStringPool.toString(attValue);
-                String  value            = unTrimValue.trim();
-                //System.out.println("value = " + value );
-                                                               //changes fTempAttDef
-                if (fValidationEnabled) {
-                    if (value != unTrimValue) {
-                        if (invalidStandaloneAttDef(element, attributeDecl.name)) {
-                            reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
-                                                      XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
-                                                      fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
-                        }
-                    }
-                }
-
-                try {
-                    if ( isAlistAttribute ) {
-                        fValENTITIES.validate( value, null );
-                    } else {
-                        fValENTITY.validate( value, null );
-                    }
-                } catch ( InvalidDatatypeValueException ex ) {
-                    if ( ex.getMajorCode() != 1 && ex.getMinorCode() != -1 ) {
-                        reportRecoverableXMLError(ex.getMajorCode(),
-                                                  ex.getMinorCode(),
-                                                  fStringPool.toString( attributeDecl.name.rawname), value );
-                    } else {
-                        System.err.println("Error: " + ex.getLocalizedMessage() );//Should not happen
-                    }
-                }
-
-                /*if (attributeDecl.list) {
-                    av = fAttValidatorENTITIES;
-                }
-                else {
-                    av = fAttValidatorENTITY;
-                }*/
-
-            }
-            break;
-        case XMLAttributeDecl.TYPE_ENUMERATION:
-            av = fAttValidatorENUMERATION;
-            break;
-        case XMLAttributeDecl.TYPE_ID:
-            {
-                String  unTrimValue = fStringPool.toString(attValue);
-                String  value       = unTrimValue.trim();
-                if (fValidationEnabled) {
-                    if (value != unTrimValue) {
-                        if (invalidStandaloneAttDef(element, attributeDecl.name)) {
-                            reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
-                                                      XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
-                                                      fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
-                        }
-                    }
-                }
-                try {
-                    //this.fIdDefs = (Hashtable) fValID.validate( value, null );
-                    //System.out.println("this.fIdDefs = " + this.fIdDefs );
-
-                    this.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
-                    fValIDRef.validate( value, this.fStoreIDRef ); //just in case we called id after IDREF
-                } catch ( InvalidDatatypeValueException ex ) {
-                    reportRecoverableXMLError(ex.getMajorCode(),
-                                              ex.getMinorCode(),
-                                              fStringPool.toString( attributeDecl.name.rawname), value );
-                }
-            }
-            break;
-        case XMLAttributeDecl.TYPE_IDREF:
-            {
-                String  unTrimValue = fStringPool.toString(attValue);
-                String  value       = unTrimValue.trim();
-                boolean isAlistAttribute = attributeDecl.list;//Caveat - Save this information because invalidStandaloneAttDef
-                                                              //changes fTempAttDef
-                if (fValidationEnabled) {
-                    if (value != unTrimValue) {
-                        if (invalidStandaloneAttDef(element, attributeDecl.name)) {
-                            reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
-                                                      XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
-                                                      fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
-                        }
-                    }
-                }
-                try {
-                    if ( isAlistAttribute ) {
-                        fValIDRefs.validate( value, this.fStoreIDRef );
-                    } else {
-                        fValIDRef.validate( value, this.fStoreIDRef );
-                    }
-                } catch ( InvalidDatatypeValueException ex ) {
-                    if ( ex.getMajorCode() != 1 && ex.getMinorCode() != -1 ) {
-                        reportRecoverableXMLError(ex.getMajorCode(),
-                                                  ex.getMinorCode(),
-                                                  fStringPool.toString( attributeDecl.name.rawname), value );
-                    } else {
-                        System.err.println("Error: " + ex.getLocalizedMessage() );//Should not happen
-                    }
-                }
-
-            }
-            break;
-        case XMLAttributeDecl.TYPE_NOTATION:
-            {
-                /* WIP
-                String  unTrimValue = fStringPool.toString(attValue);
-             String  value       = unTrimValue.trim();
-             if (fValidationEnabled) {
-                 if (value != unTrimValue) {
-                     if (invalidStandaloneAttDef(element, attributeDecl.name)) {
-                         reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
-                                                   XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
-                                                   fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
-                     }
-                 }
-             }
-             try {
-                 //this.fIdDefs = (Hashtable) fValID.validate( value, null );
-                 //System.out.println("this.fIdDefs = " + this.fIdDefs );
-
-                 this.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
-             } catch ( InvalidDatatypeValueException ex ) {
-                 reportRecoverableXMLError(ex.getMajorCode(),
-                                           ex.getMinorCode(),
-                                           fStringPool.toString( attributeDecl.name.rawname), value );
-             }
-          }
-            */
-            av = fAttValidatorNOTATION;
-
-
-            }
-            break;
-        case XMLAttributeDecl.TYPE_NMTOKEN:
-            {
-                String  unTrimValue = fStringPool.toString(attValue);
-                String  value       = unTrimValue.trim();
-                boolean isAlistAttribute = attributeDecl.list;//Caveat - Save this information because invalidStandaloneAttDef
-                //changes fTempAttDef
-                if (fValidationEnabled) {
-                    if (value != unTrimValue) {
-                        if (invalidStandaloneAttDef(element, attributeDecl.name)) {
-                            reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
-                                                      XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
-                                                      fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
-                        }
-                    }
-                }
-                try {
-                    if ( isAlistAttribute ) {
-                        fValNMTOKENS.validate( value, null );
-                    } else {
-                        fValNMTOKEN.validate( value, null );
-                    }
-                } catch ( InvalidDatatypeValueException ex ) {
-                    reportRecoverableXMLError(XMLMessages.MSG_NMTOKEN_INVALID,
-                                              XMLMessages.VC_NAME_TOKEN,
-                                              fStringPool.toString(attributeDecl.name.rawname), value);//TODO NMTOKENS messge
-                }
-
-            }
-            break;
-        }
-        if ( av != null )
-            av.normalize(element, attributeDecl.name, attValue, 
-                         attributeDecl.type, attributeDecl.enumeration);
-    }
-
-    /** Character data in content. */
-    private void charDataInContent() {
-
-        if (DEBUG_ELEMENT_CHILDREN) {
-            System.out.println("charDataInContent()");
-        }
-        if (fElementChildren.length <= fElementChildrenLength) {
-            QName[] newarray = new QName[fElementChildren.length * 2];
-            System.arraycopy(fElementChildren, 0, newarray, 0, fElementChildren.length);
-            fElementChildren = newarray;
-        }
-        QName qname = fElementChildren[fElementChildrenLength];
-        if (qname == null) {
-            for (int i = fElementChildrenLength; i < fElementChildren.length; i++) {
-                fElementChildren[i] = new QName();
-            }
-            qname = fElementChildren[fElementChildrenLength];
-        }
-        qname.clear();
-        fElementChildrenLength++;
-
-    } // charDataInCount()
-
-    /**
-     * Check that the content of an element is valid.
-     * <p>
-     * This is the method of primary concern to the validator. This method is called
-     * upon the scanner reaching the end tag of an element. At that time, the
-     * element's children must be structurally validated, so it calls this method.
-     * The index of the element being checked (in the decl pool), is provided as
-     * well as an array of element name indexes of the children. The validator must
-     * confirm that this element can have these children in this order.
-     * <p>
-     * This can also be called to do 'what if' testing of content models just to see
-     * if they would be valid.
-     * <p>
-     * Note that the element index is an index into the element decl pool, whereas
-     * the children indexes are name indexes, i.e. into the string pool.
-     * <p>
-     * A value of -1 in the children array indicates a PCDATA node. All other
-     * indexes will be positive and represent child elements. The count can be
-     * zero, since some elements have the EMPTY content model and that must be
-     * confirmed.
-     *
-     * @param elementIndex The index within the <code>ElementDeclPool</code> of this
-     *                     element.
-     * @param childCount The number of entries in the <code>children</code> array.
-     * @param children The children of this element.  Each integer is an index within
-     *                 the <code>StringPool</code> of the child element name.  An index
-     *                 of -1 is used to indicate an occurrence of non-whitespace character
-     *                 data.
-     *
-     * @return The value -1 if fully valid, else the 0 based index of the child
-     *         that first failed. If the value returned is equal to the number
-     *         of children, then additional content is required to reach a valid
-     *         ending state.
-     *
-     * @exception Exception Thrown on error.
-     */
-    private int checkContent(int elementIndex, 
-                             QName[] children,
-                             int childOffset, 
-                             int childCount) throws Exception {
-
-        // Get the element name index from the element
-        // REVISIT: Validation
-        final int elementType = fCurrentElement.rawname;
-
-        if (DEBUG_PRINT_CONTENT) {
-            String strTmp = fStringPool.toString(elementType);
-            System.out.println("Name: "+strTmp+", "+
-                               "Count: "+childCount+", "+
-                               "ContentSpecType: " +fCurrentContentSpecType); //+getContentSpecAsString(elementIndex));
-            for (int index = childOffset; index < (childOffset+childCount)  && index < 10; index++) {
-                if (index == 0) {
-                    System.out.print("  (");
-                }
-                String childName = (children[index].localpart == -1) ? "#PCDATA" : fStringPool.toString(children[index].localpart);
-                if (index + 1 == childCount) {
-                    System.out.println(childName + ")");
-                } else if (index + 1 == 10) {
-                    System.out.println(childName + ",...)");
-                } else {
-                    System.out.print(childName + ",");
-                }
-            }
-        }
-
-        // Get out the content spec for this element
-        final int contentType = fCurrentContentSpecType;
-
-// debugging
-//System.out.println("~~~~~~in checkContent, fCurrentContentSpecType : " + fCurrentContentSpecType);
-
-        //
-        //  Deal with the possible types of content. We try to optimized here
-        //  by dealing specially with content models that don't require the
-        //  full DFA treatment.
-        //
-        if (contentType == XMLElementDecl.TYPE_EMPTY) {
-            //
-            //  If the child count is greater than zero, then this is
-            //  an error right off the bat at index 0.
-            //
-            if (childCount != 0) {
-                return 0;
-            }
-        } else if (contentType == XMLElementDecl.TYPE_ANY) {
-            //
-            //  This one is open game so we don't pass any judgement on it
-            //  at all. Its assumed to fine since it can hold anything.
-            //
-        } else if (contentType == XMLElementDecl.TYPE_MIXED ||  
-                   contentType == XMLElementDecl.TYPE_CHILDREN) {
-            // Get the content model for this element, faulting it in if needed
-            XMLContentModel cmElem = null;
-            try {
-                cmElem = getElementContentModel(elementIndex);
-                int result = cmElem.validateContent(children, childOffset, childCount);
-                if (result != -1 && fGrammarIsSchemaGrammar) {
-                    // REVISIT: not optimized for performance, 
-                    EquivClassComparator comparator = new EquivClassComparator(fGrammarResolver, fStringPool);
-                    cmElem.setEquivClassComparator(comparator);
-                    result = cmElem.validateContentSpecial(children, childOffset, childCount);
-                }
-                return result;
-            } catch (CMException excToCatch) {
-                // REVISIT - Translate the caught exception to the protected error API
-                int majorCode = excToCatch.getErrorCode();
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
-                                           majorCode,
-                                           0,
-                                           null,
-                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-            }
-        } else if (contentType == -1) {
-            reportRecoverableXMLError(XMLMessages.MSG_ELEMENT_NOT_DECLARED,
-                                      XMLMessages.VC_ELEMENT_VALID,
-                                      elementType);
-        } else if (contentType == XMLElementDecl.TYPE_SIMPLE ) {
-
-            XMLContentModel cmElem = null;
-            if (childCount > 0) {
-                fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                           SchemaMessageProvider.SCHEMA_DOMAIN,
-                                           SchemaMessageProvider.DatatypeError,
-                                           SchemaMessageProvider.MSG_NONE,
-                                           new Object [] { "In element '"+fStringPool.toString(elementType)+"' : "+
-                                               "Can not have element children within a simple type content"},
-                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-            } else {
-                try {
-
-                    fGrammar.getElementDecl(elementIndex, fTempElementDecl);
-
-                    DatatypeValidator dv = fTempElementDecl.datatypeValidator;
-
-                    // If there is xsi:type validator, substitute it.
-                    if ( fXsiTypeValidator != null ) {
-                        dv = fXsiTypeValidator;
-                        fXsiTypeValidator = null;
-                    }
-
-                    if (dv == null) {
-                        System.out.println("Internal Error: this element have a simpletype "+
-                                           "but no datatypevalidator was found, element "+fTempElementDecl.name
-                                           +",locapart: "+fStringPool.toString(fTempElementDecl.name.localpart));
-                    } else {
-                        dv.validate(fDatatypeBuffer.toString(), null);
-                    }
-
-                } catch (InvalidDatatypeValueException idve) {
-                    fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                               SchemaMessageProvider.SCHEMA_DOMAIN,
-                                               SchemaMessageProvider.DatatypeError,
-                                               SchemaMessageProvider.MSG_NONE,
-                                               new Object [] { idve.getMessage()},
-                                               XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-                }
-            }
-        } else {
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                       ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
-                                       ImplementationMessages.VAL_CST,
-                                       0,
-                                       null,
-                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
-        }
-
-        // We succeeded
-        return -1;
-
-    } // checkContent(int,int,int[]):int
-
-
-    /** 
-     * Checks that all declared elements refer to declared elements
-     * in their content models. This method calls out to the error
-     * handler to indicate warnings.
-     */
-    /*private void checkDeclaredElements() throws Exception {
-
-                //****DEBUG****
-                if (DEBUG) print("(???) XMLValidator.checkDeclaredElements\n");
-                //****DEBUG****
-
-        for (int i = 0; i < fElementCount; i++) {
-            int type = fGrammar.getContentSpecType(i);
-            if (type == XMLElementDecl.TYPE_MIXED || type == XMLElementDecl.TYPE_CHILDREN) {
-                int chunk = i >> CHUNK_SHIFT;
-                int index = i &  CHUNK_MASK;
-                int contentSpecIndex = fContentSpec[chunk][index];
-                checkDeclaredElements(i, contentSpecIndex);
-            }
-        }
-    }
-    */
-
-    private void printChildren() {
-        if (DEBUG_ELEMENT_CHILDREN) {
-            System.out.print('[');
-            for (int i = 0; i < fElementChildrenLength; i++) {
-                System.out.print(' ');
-                QName qname = fElementChildren[i];
-                if (qname != null) {
-                    System.out.print(fStringPool.toString(qname.rawname));
-                } else {
-                    System.out.print("null");
-                }
-                if (i < fElementChildrenLength - 1) {
-                    System.out.print(", ");
-                }
-                System.out.flush();
-            }
-            System.out.print(" ]");
-            System.out.println();
-        }
-    }
-
-    private void printStack() {
-        if (DEBUG_ELEMENT_CHILDREN) {
-            System.out.print('{');
-            for (int i = 0; i <= fElementDepth; i++) {
-                System.out.print(' ');
-                System.out.print(fElementChildrenOffsetStack[i]);
-                if (i < fElementDepth) {
-                    System.out.print(", ");
-                }
-                System.out.flush();
-            }
-            System.out.print(" }");
-            System.out.println();
-        }
-    }
-
-
-    //
-    // Interfaces
-    //
-
-    /**
-     * AttributeValidator.
-     */
-    public interface AttributeValidator {
-
-        //
-        // AttributeValidator methods
-        //
-
-        /** Normalize. */
-        public int normalize(QName element, QName attribute, 
-                             int attValue, int attType, int enumHandle) 
-        throws Exception;
-
-    } // interface AttributeValidator
-
-
-    /** Returns true if invalid standalone attribute definition. */
-    boolean invalidStandaloneAttDef(QName element, QName attribute) {
-        if (fStandaloneReader == -1) {
-            return false;
-        }
-        // we are normalizing a default att value...  this ok?
-        if (element.rawname == -1) {
-            return false;
-        }
-        return getAttDefIsExternal(element, attribute);
-    }
-
-
-    //
-    // Classes
-    //
-
-
-    /**
-     * AttValidatorNOTATION.
-     */
-    final class AttValidatorNOTATION 
-    implements AttributeValidator {
-
-        //
-        // AttributeValidator methods
-        //
-
-        /** Normalize. */
-        public int normalize(QName element, QName attribute, 
-                             int attValueHandle, int attType, 
-                             int enumHandle) throws Exception {
-            //
-            // Normalize attribute based upon attribute type...
-            //
-            String attValue = fStringPool.toString(attValueHandle);
-            String newAttValue = attValue.trim();
-            if (fValidating) {
-                // REVISIT - can we release the old string?
-                if (newAttValue != attValue) {
-                    if (invalidStandaloneAttDef(element, attribute)) {
-                        reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
-                                                  XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
-                                                  fStringPool.toString(attribute.rawname), attValue, newAttValue);
-                    }
-                    attValueHandle = fStringPool.addSymbol(newAttValue);
-                } else {
-                    attValueHandle = fStringPool.addSymbol(attValueHandle);
-                }
-                //
-                // NOTATION - check that the value is in the AttDef enumeration (V_TAGo)
-                //
-                if (!fStringPool.stringInList(enumHandle, attValueHandle)) {
-                    reportRecoverableXMLError(XMLMessages.MSG_ATTRIBUTE_VALUE_NOT_IN_LIST,
-                                              XMLMessages.VC_NOTATION_ATTRIBUTES,
-                                              fStringPool.toString(attribute.rawname),
-                                              newAttValue, fStringPool.stringListAsString(enumHandle));
-                }
-            } else if (newAttValue != attValue) {
-                // REVISIT - can we release the old string?
-                attValueHandle = fStringPool.addSymbol(newAttValue);
-            }
-            return attValueHandle;
-
-        } // normalize(QName,QName,int,int,int):int
-
-        //
-        // Package methods
-        //
-
-        /** Returns true if invalid standalone attribute definition. */
-        boolean invalidStandaloneAttDef(QName element, QName attribute) {
-            if (fStandaloneReader == -1) {
-                return false;
-            }
-            // we are normalizing a default att value...  this ok?
-            if (element.rawname == -1) {
-                return false;
-            }
-            return getAttDefIsExternal(element, attribute);
-        }
-
-    } // class AttValidatorNOTATION
-
-    /**
-     * AttValidatorENUMERATION.
-     */
-    final class AttValidatorENUMERATION 
-    implements AttributeValidator {
-
-        //
-        // AttributeValidator methods
-        //
-
-        /** Normalize. */
-        public int normalize(QName element, QName attribute, 
-                             int attValueHandle, int attType, 
-                             int enumHandle) throws Exception {
-            //
-            // Normalize attribute based upon attribute type...
-            //
-            String attValue = fStringPool.toString(attValueHandle);
-            String newAttValue = attValue.trim();
-            if (fValidating) {
-                // REVISIT - can we release the old string?
-                if (newAttValue != attValue) {
-                    if (invalidStandaloneAttDef(element, attribute)) {
-                        reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
-                                                  XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
-                                                  fStringPool.toString(attribute.rawname), attValue, newAttValue);
-                    }
-                    attValueHandle = fStringPool.addSymbol(newAttValue);
-                } else {
-                    attValueHandle = fStringPool.addSymbol(attValueHandle);
-                }
-                //
-                // ENUMERATION - check that value is in the AttDef enumeration (V_TAG9)
-                //
-                if (!fStringPool.stringInList(enumHandle, attValueHandle)) {
-                    reportRecoverableXMLError(XMLMessages.MSG_ATTRIBUTE_VALUE_NOT_IN_LIST,
-                                              XMLMessages.VC_ENUMERATION,
-                                              fStringPool.toString(attribute.rawname),
-                                              newAttValue, fStringPool.stringListAsString(enumHandle));
-                }
-            } else if (newAttValue != attValue) {
-                // REVISIT - can we release the old string?
-                attValueHandle = fStringPool.addSymbol(newAttValue);
-            }
-            return attValueHandle;
-
-        } // normalize(QName,QName,int,int,int):int
-
-        //
-        // Package methods
-        //
-
-        /** Returns true if invalid standalone attribute definition. */
-        boolean invalidStandaloneAttDef(QName element, QName attribute) {
-            if (fStandaloneReader == -1) {
-                return false;
-            }
-            // we are normalizing a default att value...  this ok?
-            if (element.rawname == -1) {
-                return false;
-            }
-            return getAttDefIsExternal(element, attribute);
-        }
-
-    } // class AttValidatorENUMERATION
-
-} // class XMLValidator
diff --git a/src/org/apache/xerces/validators/datatype/AbstractDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/AbstractDatatypeValidator.java
deleted file mode 100644
index 1d3419e..0000000
--- a/src/org/apache/xerces/validators/datatype/AbstractDatatypeValidator.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-/**
- * @version $Id$
- * @author  Jeffrey Rodriguez
-*/
-
-
-
-package org.apache.xerces.validators.datatype;
-import java.util.Hashtable;
-import org.apache.xerces.validators.datatype.DatatypeValidator;
-
-
-public abstract class AbstractDatatypeValidator implements DatatypeValidator, Cloneable {
-
-    private Hashtable fFacets; // Hashtable of Facets Strings.
-
-    //abstract public AbstractDatatypeValidator();
-    //public AbstractDatatypeValidator(){
-    //}
-
-
-    //abstract public AbstractDatatypeValidator ( DatatypeValidator base, Hashtable facets, 
-      //                                 boolean list ); 
-
-    //public AbstractDatatypeValidator ( DatatypeValidator base, Hashtable facets, 
-    //                                                                boolean list ){ 
-    //
-    //
-    //}
-
-    /**
-     * Checks that "content" string is valid
-     * datatype.
-     * If invalid a Datatype validation exception is thrown.
-     *
-     * @param content A string containing the content to be validated
-     * @param derivedBylist
-     *                Flag which is true when type
-     *                is derived by list otherwise it
-     *                it is derived by extension.
-     *
-     * @exception throws InvalidDatatypeException if the content is
-     *                   invalid according to the rules for the validators
-     * @exception InvalidDatatypeValueException
-     * @see         org.apache.xerces.validators.datatype.InvalidDatatypeValueException
-     */
-    abstract public Object validate(String content, Object state) throws InvalidDatatypeValueException;
-
-    //{ 
-     //   System.out.println( "Here in AbstracDatatype " + content );
-      //  return null;
-    //}
-
-
-    abstract public Object clone() throws CloneNotSupportedException ;
-
-
-    /**
-     * returns the datatype facet if any is set as a
-     * Hashtable
-     *
-     * @return
-     */
-    public Hashtable getFacets() {
-        return null;  // Not implemented yet
-    }
-    /**
-     * Compares content in the Domain value vs. lexical
-     * value.
-     * e.g. If type is a float then 1.0 may be equivalent
-     * to 1 even tough both are lexically different.
-     *
-     * @param value1
-     * @param valu2
-     * @return
-     */
-    public int compare(String value1, String valu2) {
-        return 0;     //Not implemented yet 
-    }
-
-
-}
diff --git a/src/org/apache/xerces/validators/datatype/BinaryDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/BinaryDatatypeValidator.java
deleted file mode 100644
index 027fd3b..0000000
--- a/src/org/apache/xerces/validators/datatype/BinaryDatatypeValidator.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Locale;
-import java.util.Vector;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-import org.apache.xerces.utils.regex.RegularExpression;
-import org.apache.xerces.utils.Base64;
-import org.apache.xerces.utils.HexBin;
-
-
-/**
- *
- * binaryValidator validates that XML content is a W3C binary type.
- *
- * @author Ted Leung
- * @author Jeffrey Rodriguez
- * @version $Id$
- */
-
-public class BinaryDatatypeValidator extends AbstractDatatypeValidator {
-    private DatatypeValidator  fBaseValidator   = null; //Basetype null means this is a native type
-    private int                fLength          = 0;
-    private int                fMaxLength       = Integer.MAX_VALUE;
-    private int                fMinLength       = 0;
-    private String             fPattern         = null;
-    private Vector             fEnumeration     = null;
-    private int                fFacetsDefined   = 0;
-    private String             fEncoding        = SchemaSymbols.ATTVAL_BASE64;//default Base64 encoding
-    private boolean            fDerivedByList   = false; // Default is restriction 
-
-    public BinaryDatatypeValidator () throws InvalidDatatypeFacetException {
-        this( null, null, false ); // Native, No Facets defined, Restriction
-    }
-
-    public BinaryDatatypeValidator ( DatatypeValidator base, Hashtable facets, 
-                                     boolean derivedByList ) throws InvalidDatatypeFacetException {
-        if ( base != null )
-            setBasetype( base ); // Set base type 
-
-        fDerivedByList = derivedByList;
-
-        // Set Facets if any defined
-
-        if ( facets != null  )  {
-            if ( fDerivedByList == false ) {
-                for (Enumeration e = facets.keys(); e.hasMoreElements();) {
-                    String key = (String) e.nextElement();
-                    if ( key.equals(SchemaSymbols.ELT_LENGTH ) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_LENGTH;
-                        String lengthValue = (String)facets.get(key);
-                        try {
-                            fLength     = Integer.parseInt( lengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("Length value '"+
-                                                                    lengthValue+"' is invalid.");
-                        }
-                        if ( fLength < 0 )
-                            throw new InvalidDatatypeFacetException("Length value '"+
-                                                                    lengthValue+"'  must be a nonNegativeInteger.");
-
-                    } else if (key.equals(SchemaSymbols.ELT_MINLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MINLENGTH;
-                        String minLengthValue = (String)facets.get(key);
-                        try {
-                            fMinLength     = Integer.parseInt( minLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("maxLength value '"+minLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MAXLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXLENGTH;
-                        String maxLengthValue = (String)facets.get(key);
-                        try {
-                            fMaxLength     = Integer.parseInt( maxLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("maxLength value '"+maxLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_PATTERN)) {
-                        fFacetsDefined += DatatypeValidator.FACET_PATTERN;
-                        fPattern = (String)facets.get(key);
-                    } else if (key.equals(SchemaSymbols.ELT_ENUMERATION)) {
-                        fFacetsDefined += DatatypeValidator.FACET_ENUMERATION;
-                        fEnumeration = (Vector)facets.get(key);
-                    } else if (key.equals(SchemaSymbols.ELT_ENCODING )) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXINCLUSIVE;
-                        fEncoding = (String)facets.get(key);
-                    } else {
-                        throw new InvalidDatatypeFacetException();
-                    }
-                }
-                if (((fFacetsDefined & DatatypeValidator.FACET_LENGTH ) != 0 ) ) {
-                    if (((fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and maxLength to be members of facets." );  
-                    } else if (((fFacetsDefined & DatatypeValidator.FACET_MINLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and minLength to be members of facets." );
-                    }
-                }
-
-                if ( ( (fFacetsDefined & ( DatatypeValidator.FACET_MINLENGTH |
-                                           DatatypeValidator.FACET_MAXLENGTH) ) != 0 ) ) {
-                    if ( fMinLength > fMaxLength ) {
-                        throw new InvalidDatatypeFacetException( "Value of maxLength = " + fMaxLength +
-                                                                 "must be greater that the value of minLength" + fMinLength );
-                    }
-                }
-            } else {  //Derivation by List 
-            }
-        }// End of Facet setting
-    }
-
-
-
-    /**
-     * validate that a string is a W3C binary type
-     *
-     * validate returns true or false depending on whether the string content is an
-     * instance of the W3C binary datatype
-     *
-     * @param content A string containing the content to be validated
-     *
-     * @exception throws InvalidDatatypeException if the content is
-     *  not a W3C binary type
-     */
-    public Object validate(String content, Object state ) throws InvalidDatatypeValueException {
-
-        if ( fDerivedByList == false) { //derived by restriction
-            if ( this.fBaseValidator != null ) {//validate against parent type if any
-                this.fBaseValidator.validate( content, state );
-            }
-
-            if (((fFacetsDefined & DatatypeValidator.FACET_ENCODING) != 0 ) ){ //Encode defined then validate
-                if ( fEncoding.equals( SchemaSymbols.ATTVAL_BASE64)){ //Base64
-                    if ( Base64.isBase64( content ) == false ) {
-                        throw new InvalidDatatypeValueException( "Value '"+
-                                                                 content+ "'  must be" + "is not encoded in Base64" );
-                    }
-                } else { //HexBin
-                    if ( HexBin.isHex( content ) == false ){
-                        throw new InvalidDatatypeValueException( "Value '"+
-                                                                 content+ "'  must be" + "is not encoded in Hex" );
-                    }
-                }
-            }
-        } else{ //derived by list - What does it mean for binary types?
-        }
-        return null;
-    }
-
-    /**
-     * Compare two Binary Datatype Lexical values.
-     * 
-     * @param content1
-     * @param content2
-     * @return 
-     */
-    public int compare( String content1, String content2){
-        return 0;
-    }
-
-    /**
-     * Returns a Hastable that represent the facets
-     * state of the datatype.
-     * 
-     * @return 
-     */
-    public Hashtable getFacets(){
-        return null;
-    }
-
-
-    /**
-    * Returns a copy of this object.
-    */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
-    }
-
-    //Private methods
-
-    /**
-     * Set base type
-     * 
-     * @param base
-     */
-    private void setBasetype(DatatypeValidator base) {
-        fBaseValidator = base;
-    }
-
-
-
-}
diff --git a/src/org/apache/xerces/validators/datatype/BooleanDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/BooleanDatatypeValidator.java
deleted file mode 100644
index 599ce81..0000000
--- a/src/org/apache/xerces/validators/datatype/BooleanDatatypeValidator.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.Hashtable;
-import java.util.Locale;
-import java.util.Enumeration;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-import org.apache.xerces.utils.regex.RegularExpression;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-import org.apache.xerces.validators.datatype.InvalidDatatypeFacetException;
-/**
- *
- * BooleanValidator validates that content satisfies the W3C XML Datatype for Boolean
- *
- * @author Ted Leung 
- * @author Jeffrey Rodriguez
- * @version  $Id$
- */
-
-public class BooleanDatatypeValidator extends AbstractDatatypeValidator {
-    private Locale                  fLocale          = null;
-    private DatatypeValidator       fBaseValidator   = null; //Basetype null means we are a native type
-    private String                  fPattern         = null;
-    private int                     fFacetsDefined   = 0;
-    private DatatypeMessageProvider fMessageProvider = new DatatypeMessageProvider();
-    private static  final String    fValueSpace[]    = { "false", "true", "0", "1"};
-    private boolean                 fDerivedByList   = false;
-    private RegularExpression       fRegex           = null;
-
-    public BooleanDatatypeValidator () throws InvalidDatatypeFacetException {
-       this( null, null, false ); // Native, No Facets defined, Restriction
-    }
-
-    public BooleanDatatypeValidator ( DatatypeValidator base, Hashtable facets,
-                 boolean derivedByList ) throws InvalidDatatypeFacetException {
-        setBasetype( base ); // Set base type 
-
-        fDerivedByList = derivedByList;
-
-        // Set Facets if any defined
-        if ( facets != null  ) { 
-            if ( derivedByList == false ) {
-                for (Enumeration e = facets.keys(); e.hasMoreElements();) {
-                    String key = (String) e.nextElement();
-
-                    if (key.equals(SchemaSymbols.ELT_PATTERN)) {
-                        fFacetsDefined += DatatypeValidator.FACET_PATTERN;
-                        fPattern = (String)facets.get(key);
-                        if( fPattern != null )
-                           fRegex = new RegularExpression(fPattern, "X" );
-                    } else {
-                        throw new
-                           InvalidDatatypeFacetException( 
-                                "Only constraining facet in boolean datatype is PATTERN" );
-                    }
-                }
-            } else { // By List
-
-            }
-        }// End of facet setting
-    }
-
-
-    /**
-     * validate that a string matches the boolean datatype
-     * @param content A string containing the content to be validated
-     *
-     * @exception throws InvalidDatatypeException if the content is
-     * is not valid.
-     */
-
-    public Object validate(String content, Object state) throws InvalidDatatypeValueException {
-
-        if ( fDerivedByList == true ) {
-            ;// What does it mean?
-        } else {
-            checkContent( content );
-        }
-        return null;
-    }
-
-
-    /**
-     * Compare two boolean data types
-     * 
-     * @param content1
-     * @param content2
-     * @return 
-     */
-    public int compare( String content1, String content2){
-        return 0;
-    }
-
-    /**
-     * Return a Hashtable that contains facet information
-     * 
-     * @return Hashtable
-     */
-
-    public Hashtable getFacets(){
-        return null;
-    }
-
-
-    //Begin private method definitions
-
-    /**
-     * Sets the base datatype name.
-     * 
-     * @param base
-     */
-
-    private  void setBasetype(DatatypeValidator base) {
-        fBaseValidator = base;
-    }
-
-
-
-    private String getErrorString(int major, int minor, Object args[]) {
-        try {
-            return fMessageProvider.createMessage(fLocale, major, minor, args);
-        } catch (Exception e) {
-            return "Illegal Errorcode "+minor;
-        }
-    }
-  /**
-     * Returns a copy of this object.
-     */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
-    }
-
-
-    /**
-     * Checks content for validity.
-     * 
-     * @param content
-     * @exception InvalidDatatypeValueException
-     */
-    private void checkContent( String content )throws InvalidDatatypeValueException {
-        boolean  isContentInDomain = false;
-        for ( int i = 0;i<fValueSpace.length;i++ ) {
-            if ( content.equals(fValueSpace[i] ) )
-                isContentInDomain = true;
-        }
-        if (isContentInDomain == false)
-            throw new InvalidDatatypeValueException(
-                                                   getErrorString(DatatypeMessageProvider.NotBoolean,
-                                                                  DatatypeMessageProvider.MSG_NONE,
-                                                                  new Object[] { content}));
-        if ( (fFacetsDefined & DatatypeValidator.FACET_PATTERN ) != 0 ) {
-            if ( fRegex == null || fRegex.matches( content) == false )
-                throw new InvalidDatatypeValueException("Value'"+content+
-                                                        "does not match regular expression facet" + fPattern );
-        }
-    }
-}
diff --git a/src/org/apache/xerces/validators/datatype/DatatypeMessageProvider.java b/src/org/apache/xerces/validators/datatype/DatatypeMessageProvider.java
deleted file mode 100644
index 823282b..0000000
--- a/src/org/apache/xerces/validators/datatype/DatatypeMessageProvider.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.ListResourceBundle;
-import java.util.Locale;
-import java.util.ResourceBundle;
-import org.apache.xerces.utils.XMLMessageProvider;
-
-/**
- * 
- * @author Jeffrey Rodriguez
- * @version $Id$
- */
-public class DatatypeMessageProvider implements XMLMessageProvider {
-    /**
-     * The domain of messages concerning the XML Schema: Datatypes specification.
-     */
-    public static final String DATATYPE_DOMAIN = "http://www.w3.org/TR/xml-schema-2";
-
-    /**
-     * Set the locale used for error messages
-     *
-     * @param locale the new locale
-     */
-    public void setLocale(Locale locale) {
-        fLocale = locale;
-    }
-    /**
-     * get the local used for error messages
-     *
-     * @return the locale
-     */
-    public Locale getLocale() {
-        return fLocale;
-    }
-
-    /**
-     * Creates a message from the specified key and replacement
-     * arguments, localized to the given locale.
-     *
-     * @param locale    The requested locale of the message to be
-     *                  created.
-     * @param key       The key for the message text.
-     * @param args      The arguments to be used as replacement text
-     *                  in the message created.
-     */
-    public String createMessage(Locale locale, int majorCode, int minorCode, Object args[]) {
-        boolean throwex = false;
-        if (fResourceBundle == null || locale != fLocale) {
-            if (locale != null)
-                fResourceBundle = ListResourceBundle.getBundle("org.apache.xerces.msg.DatatypeMessages", locale);
-            if (fResourceBundle == null)
-                fResourceBundle = ListResourceBundle.getBundle("org.apache.xerces.msg.DatatypeMessages");
-        }
-        if (majorCode < 0 || majorCode >= fgMessageKeys.length) {
-            majorCode = MSG_BAD_MAJORCODE;
-            throwex = true;
-        }
-        String msgKey = fgMessageKeys[majorCode];
-        String msg = fResourceBundle.getString(msgKey);
-        if (args != null) {
-            try {
-                msg = java.text.MessageFormat.format(msg, args);
-            } catch (Exception e) {
-                msg = fResourceBundle.getString(fgMessageKeys[MSG_FORMAT_FAILURE]);
-                msg += " " + fResourceBundle.getString(msgKey);
-            }
-        }
-
-        if (throwex) {
-            throw new RuntimeException(msg);
-        }
-        return msg;
-    }
-    //
-    //
-    //
-    private Locale fLocale = null;
-    private ResourceBundle fResourceBundle = null;
-    //
-    // Major Codes
-    //
-    public static final int 
-        MSG_BAD_MAJORCODE = 0,              //  majorCode parameter to createMessage was out of bounds
-        MSG_FORMAT_FAILURE = 1,             //  exception thrown during messageFormat call
-        NotBoolean = 2,
-        NotDecimal = 3,
-        FacetsInconsistent = 4,
-        IllegalFacetValue = 5,
-        IllegalDecimalFacet = 6,
-        UnknownFacet = 7,
-        InvalidEnumValue = 8,
-        OutOfBounds = 9,
-        NotAnEnumValue = 10,
-        NotInteger = 11,
-        IllegalIntegerFacet = 12,
-        NotReal = 13,
-        IllegalRealFacet = 14,
-        ScaleLargerThanPrecision = 15,
-        PrecisionExceeded = 16,
-        ScaleExceeded = 17,
-        NotFloat = 18,
-       // ...
-        MSG_MAX_CODE = 19;
-
-    //
-    // Minor Codes
-    //
-    public static final int
-        MSG_NONE = 0;
-
-    public static final String[] fgMessageKeys = {
-        "BadMajorCode",                 //   0, "The majorCode parameter to createMessage was out of bounds."
-        "FormatFailed",                 //   1, "An internal error occurred while formatting the following message:"
-        "NotBoolean",                   //   2, "{0} is not a boolean"
-        "NotDecimal",                   //   3, "{0} is not a decimal"
-        "FacetsInconsistent",           //   4, "Facets are inconsistent with base type"
-        "IllegalFacetValue",            //   5, "Illegal value {0} for facet {1}."
-        "IllegalDecimalFacet",          //   6, "Illegal Facet for decimal type"
-        "UnknownFacet",                 //   7, "Unknown Facet: {0}"
-        "InvalidEnumValue",             //   8, "Invalid value for Enum constant: {0}"
-        "OutOfBounds",                  //   9, "{0} is out of bounds."
-        "NotAnEnumValue",               //  10, "{0} is not one of the specified enum values."
-        "NotInteger",                   //  11, "{0} is not an integer."
-        "IllegalIntegerFacet",          //  12, "Illegal Facet for Integer type."
-        "NotReal",                      //  13, "{0} is not a double."
-        "IllegalRealFacet",             //  14, "Illegal Facet for Real type."
-        "ScaleLargerThanPrecision",     //  15, "Scale Facet must be less than or equal to Precision Facet"
-        "PrecisionExceeded",            //  16, "{0} has exceeded the precision Facet {1}"},
-        "ScaleExceeded",                //  17, "{0} has execeed the scale Facet {1}"},
-        "NotFloat"                     //  18, "{0} is not a float."
-
-    };
-
-}
diff --git a/src/org/apache/xerces/validators/datatype/DatatypeValidator.java b/src/org/apache/xerces/validators/datatype/DatatypeValidator.java
deleted file mode 100644
index 42b4da3..0000000
--- a/src/org/apache/xerces/validators/datatype/DatatypeValidator.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.Hashtable;
-import java.util.Locale;
-
-/**
- * DataTypeValidator defines the interface that data type validators must obey.
- * These validators can be supplied by the application writer and may be useful as
- * standalone code as well as plugins to the validator architecture.
- * Note: there is no support for facets in this API, since we are trying to convince
- * W3C to remove facets from the data type spec.
- * 
- * @author Jeffrey Rodriguez-
- * @version $Id$
- */
-public interface DatatypeValidator {
-    public static final int FACET_LENGTH       = 1;
-    public static final int FACET_MINLENGTH    = 1<<1;
-    public static final int FACET_MAXLENGTH    = 1<<2;
-    public static final int FACET_PATTERN      = 1<<3; 
-    public static final int FACET_ENUMERATION  = 1<<4;
-    public static final int FACET_MAXINCLUSIVE = 1<<5;
-    public static final int FACET_MAXEXCLUSIVE = 1<<6;
-    public static final int FACET_MININCLUSIVE = 1<<7;
-    public static final int FACET_MINEXCLUSIVE = 1<<8;
-    public static final int FACET_PRECISSION   = 1<<9;
-    public static final int FACET_SCALE        = 1<<10;
-    public static final int FACET_ENCODING     = 1<<11;
-    public static final int FACET_DURATION     = 1<<12;
-    public static final int FACET_PERIOD       = 1<<13;
-
-
-
-    /**
-     * Checks that "content" string is valid 
-     * datatype.
-     * If invalid a Datatype validation exception is thrown.
-     * 
-     * @param content A string containing the content to be validated
-     * @param derivedBylist
-     *                Flag which is true when type
-     *                is derived by list otherwise it
-     *                it is derived by extension.
-     *                
-     * @exception throws InvalidDatatypeException if the content is
-     *                   invalid according to the rules for the validators
-     * @exception InvalidDatatypeValueException
-     * @see         org.apache.xerces.validators.datatype.InvalidDatatypeValueException
-     */
-    public Object validate(String content, Object state ) throws InvalidDatatypeValueException;
-
-
-    /**
-     * returns the datatype facet if any is set as a
-     * Hashtable
-     * 
-     * @return 
-     */
-    public Hashtable getFacets();
-
-
-    /**
-     * Compares content in the Domain value vs. lexical
-     * value.
-     * e.g. If type is a float then 1.0 may be equivalent
-     * to 1 even tough both are lexically different.
-     * 
-     * @param value1
-     * @param valu2
-     * @return 
-     */
-    public int compare( String value1, String value2);
-
-}
diff --git a/src/org/apache/xerces/validators/datatype/DatatypeValidatorFactory.java b/src/org/apache/xerces/validators/datatype/DatatypeValidatorFactory.java
deleted file mode 100644
index efe00d4..0000000
--- a/src/org/apache/xerces/validators/datatype/DatatypeValidatorFactory.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-import java.util.Hashtable;
-import org.apache.xerces.validators.datatype.*;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-
-
-/**
- * @version $Id$
- * @author  Jeffrey Rodriguez
- */
-public interface DatatypeValidatorFactory {
-    public DatatypeValidator createDatatypeValidator(String typeName, 
-                    DatatypeValidator base, Hashtable facets, boolean list ) throws  InvalidDatatypeFacetException;
-}
-
diff --git a/src/org/apache/xerces/validators/datatype/DatatypeValidatorFactoryImpl.java b/src/org/apache/xerces/validators/datatype/DatatypeValidatorFactoryImpl.java
deleted file mode 100644
index 36901bd..0000000
--- a/src/org/apache/xerces/validators/datatype/DatatypeValidatorFactoryImpl.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-import java.util.Hashtable;
-import java.lang.reflect.*;
-import org.apache.xerces.validators.datatype.*;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-import org.apache.xerces.validators.datatype.DatatypeValidatorFactory;
-import org.apache.xerces.validators.datatype.InvalidDatatypeFacetException;
-
-
-
-
-/**
- * @version $Id$
- * @author  Jeffrey Rodriguez
- */
-
-public class DatatypeValidatorFactoryImpl implements DatatypeValidatorFactory {
-    private static final boolean fDebug = false;
-    private static DatatypeValidatorFactoryImpl _instance = new DatatypeValidatorFactoryImpl();
-    private Hashtable fRegistry = new Hashtable();
-
-
-    private DatatypeValidatorFactoryImpl() {
-        initializeRegistry();
-    }
-
-    /**
-     * Initializes registry with primitive and derived
-     * Simple types.
-     */
-    void initializeRegistry() {
-        DatatypeValidator  v = null;
-
-        //Register Primitive Datatypes 
-
-        try {
-            fRegistry.put("string",            new StringDatatypeValidator() );
-            fRegistry.put("boolean",           new BooleanDatatypeValidator()  );
-            fRegistry.put("float",             new FloatDatatypeValidator());
-            fRegistry.put("double",            new DoubleDatatypeValidator());
-            fRegistry.put("decimal",           new DecimalDatatypeValidator());
-            fRegistry.put("timeDuration",      new TimeDurationDatatypeValidator());
-            fRegistry.put("recurringDuration", new RecurringDurationDatatypeValidator());
-            fRegistry.put("binary",            new BinaryDatatypeValidator());
-            fRegistry.put("uriReference",      new URIReferenceDatatypeValidator());
-            fRegistry.put("ID",                new IDDatatypeValidator());
-            fRegistry.put("IDREF",             new IDREFDatatypeValidator());
-            fRegistry.put("ENTITY",            new ENTITYDatatypeValidator());
-            fRegistry.put("NOTATION",          new NOTATIONDatatypeValidator());
-            fRegistry.put("QName",             new QNameDatatypeValidator()); 
-
-
-            Hashtable facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_PATTERN , "([a-zA-Z]{2}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]+)(-[a-zA-Z]+)*" );
-            
-            createDatatypeValidator("language", new StringDatatypeValidator() , facets,
-                                                 false );
-
-            createDatatypeValidator( "IDREFS", new IDREFDatatypeValidator(), null , true );
-
-            createDatatypeValidator( "ENTITIES", new ENTITYDatatypeValidator(),  null, true );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_PATTERN , "\\c+" );
-            createDatatypeValidator("NMTOKEN", new StringDatatypeValidator(), facets, false );
-
-            createDatatypeValidator("NMTOKENS",  
-                                                 getDatatypeValidator( "NMTOKEN" ), null, true );
-
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_PATTERN , "\\i\\c*" );
-            createDatatypeValidator("Name", new StringDatatypeValidator(), facets, false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_PATTERN , "[\\i-[:]][\\c-[:]]*"  );
-            createDatatypeValidator("NCName", new StringDatatypeValidator(), facets, false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_SCALE, "0");
-            createDatatypeValidator("integer", new DecimalDatatypeValidator(), facets, false);
-
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_MAXINCLUSIVE , "0" );
-            createDatatypeValidator("nonPositiveInteger", 
-                                                 getDatatypeValidator("integer"), facets, false );
-
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_MAXINCLUSIVE , "-1" );
-            createDatatypeValidator("negativeInteger", 
-                                                 getDatatypeValidator( "nonPositiveInteger"), facets, false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_MAXINCLUSIVE , "9223372036854775807");
-            facets.put(SchemaSymbols.ELT_MININCLUSIVE,  "-9223372036854775808");
-            createDatatypeValidator("long", getDatatypeValidator( "integer"), facets, false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_MAXINCLUSIVE , "2147483647");
-            facets.put(SchemaSymbols.ELT_MININCLUSIVE,  "-2147483648");
-            createDatatypeValidator("int", getDatatypeValidator( "long"), facets,false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_MAXINCLUSIVE , "32767");
-            facets.put(SchemaSymbols.ELT_MININCLUSIVE,  "-32768");
-            createDatatypeValidator("short", getDatatypeValidator( "int"), facets, false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_MAXINCLUSIVE , "127");
-            facets.put(SchemaSymbols.ELT_MININCLUSIVE,  "-128");
-            createDatatypeValidator("byte",
-                                        getDatatypeValidator( "short"), facets, false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_MININCLUSIVE, "0" );
-            createDatatypeValidator("nonNegativeInteger", 
-                                          getDatatypeValidator( "integer"), facets, false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_MAXINCLUSIVE, "18446744073709551615" );
-            createDatatypeValidator("unsignedLong",
-                                                 getDatatypeValidator( "nonNegativeInteger"), facets, false );
-
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_MAXINCLUSIVE, "4294967295" );
-            createDatatypeValidator("unsignedInt",
-                                                 getDatatypeValidator( "unsignedLong"), facets, false );
-
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_MAXINCLUSIVE, "65535" );
-            createDatatypeValidator("unsignedShort", 
-                                                 getDatatypeValidator( "unsignedInt"), facets, false );
-
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_MAXINCLUSIVE, "255" );
-            createDatatypeValidator("unsignedByte",
-                                                 getDatatypeValidator( "unsignedShort"), facets, false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_MININCLUSIVE, "1" );
-            createDatatypeValidator("positiveInteger",
-                                                 getDatatypeValidator( "nonNegativeInteger"), facets, false );
-
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_DURATION, "P0Y" );
-            facets.put(SchemaSymbols.ELT_PERIOD,   "P0Y" );
-            createDatatypeValidator("timeInstant", 
-                                                 getDatatypeValidator( "recurringDuration"),facets, false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_DURATION, "P0Y" );
-//            facets.put(SchemaSymbols.ELT_PERIOD,   "PY24H" ); Bug -- WORK TODO
-            createDatatypeValidator("time", 
-                                                 getDatatypeValidator( "recurringDuration"), facets, false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_PERIOD,   "P0Y" );
-            createDatatypeValidator("timePeriod", 
-                                                 getDatatypeValidator( "recurringDuration"), facets, false );
-
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_DURATION, "PT24H" );
-            createDatatypeValidator("date",
-                                                 getDatatypeValidator( "timePeriod"), facets, false );
-
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_DURATION, "P1M" );
-            createDatatypeValidator("month",
-                                                 getDatatypeValidator( "timePeriod"), facets, false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_DURATION, "P1Y" );
-            createDatatypeValidator("year", 
-                                                 getDatatypeValidator( "timePeriod"), facets, false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_DURATION, "P100Y" );
-            createDatatypeValidator("century", 
-                                                 getDatatypeValidator( "timePeriod"), facets, false );
-
-            facets = new Hashtable();
-            facets.put(SchemaSymbols.ELT_PERIOD, "P1Y" );
-            facets.put(SchemaSymbols.ELT_DURATION, "PT24H" );
-            createDatatypeValidator("recurringDate",
-                                                 getDatatypeValidator( "recurringDuration"),facets, false );
-        } catch ( InvalidDatatypeFacetException ex ){
-            ex.printStackTrace();
-        }
-    }
-
-    public void resetRegistry(){
-        fRegistry.clear();
-        initializeRegistry();
-    }
-
-    public DatatypeValidator createDatatypeValidator(String typeName, 
-            DatatypeValidator base, Hashtable facets, boolean list ) throws InvalidDatatypeFacetException {
-
-        DatatypeValidator simpleType = null;
-
-        if (this.fDebug == true) {
-            System.out.println("type name = " + typeName );
-        }
-
-        if ( base != null ) {
-            try {
-                Class validatorDef = base.getClass();
-
-                Class [] validatorArgsClass = new Class[] {  
-                    org.apache.xerces.validators.datatype.DatatypeValidator.class,
-                    java.util.Hashtable.class,
-                    boolean.class};
-
-
-
-                Object [] validatorArgs     = new Object[] {
-                    base, facets, new Boolean( list )};
-
-
-
-
-                Constructor validatorConstructor =
-                validatorDef.getConstructor( validatorArgsClass );
-
-
-                simpleType = 
-                ( DatatypeValidator ) createDatatypeValidator (
-                                                 validatorConstructor, validatorArgs );
-
-                if (simpleType != null) {
-                    addValidator( typeName, simpleType );//register validator
-                }
-
-
-            } catch (NoSuchMethodException e) {
-                e.printStackTrace();
-            }
-
-        }
-        return simpleType;// return it
-    }
-
-
-
-    private static Object createDatatypeValidator(Constructor validatorConstructor, 
-                   Object[] arguments)  throws  InvalidDatatypeFacetException {
-        Object validator = null;
-        try {
-            validator = validatorConstructor.newInstance(arguments);
-            return validator;
-        } catch (InstantiationException e) {
-            if( fDebug ){
-                e.printStackTrace();
-            }else {
-                return null;
-            }
-        } catch (IllegalAccessException e) {
-            if( fDebug ){
-                e.printStackTrace();
-            }else {
-                return null;
-            }
-        } catch (IllegalArgumentException e) {
-            if( fDebug ){
-                e.printStackTrace();
-            }else {
-                return null;
-            }
-        } catch (InvocationTargetException e) {
-            if ( fDebug ){
-                System.out.println("!! The original error message is: " + e.getTargetException().getMessage() );
-                e.getTargetException().printStackTrace();
-            } else {
-                 throw new InvalidDatatypeFacetException( e.getTargetException().getMessage() );
-                //System.out.println("Exception: " + e.getTargetException
-                //validator = null;
-            }
-        }
-        return validator;
-    }
-
-
-    public DatatypeValidator getDatatypeValidator(String type) {
-        AbstractDatatypeValidator simpleType = null;
-        if( fDebug ) {
-            System.out.println( "type = >" + type +"<");
-            System.out.println( "fRegistry = >" + fRegistry +"<" );
-            simpleType = (AbstractDatatypeValidator) fRegistry.get(type);
-        }
-        if ( type != null && fRegistry != null
-                          && fRegistry.containsKey( type ) == true ) {
-            simpleType = (AbstractDatatypeValidator) fRegistry.get(type);
-
-            // This code is not needed after all.
-            // and it is a potential performance hit.
-            //if ( simpleType != null ) { // if not registered type to create one
-              //  try {
-               //     simpleType  = (AbstractDatatypeValidator) simpleType.clone();
-                //} catch (CloneNotSupportedException cloneExc) {
-                  //  try {
-                   //     simpleType = (AbstractDatatypeValidator) simpleType.getClass().newInstance(); 
-                   // } catch( InstantiationException e ) {
-                    //    e.printStackTrace();
-                   // } catch( IllegalAccessException e ) {
-                    //    e.printStackTrace();
-                    //}
-                 //}
-            //}
-        }
-        return (DatatypeValidator) simpleType;
-    }
-
-    private void addValidator(String name, DatatypeValidator v) {
-        fRegistry.put(name,v);
-    }
-
-    static public DatatypeValidatorFactoryImpl getDatatypeRegistry()  {
-        return _instance;
-    }
-
-    static public void main( String argv[] ){
-        DatatypeValidatorFactoryImpl  tstRegistry = DatatypeValidatorFactoryImpl.getDatatypeRegistry();
-
-
-        DatatypeValidator   tstData1            = tstRegistry.getDatatypeValidator( "NTOKEN" );
-        DatatypeValidator   tstData2            = tstRegistry.getDatatypeValidator( "NTOKENS" );
-
-        System.out.println( "NMTOKEN = " + tstData1 );
-        System.out.println( "NMTOKENS = " + tstData2 );
-
-    }
-}
-
diff --git a/src/org/apache/xerces/validators/datatype/DecimalDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/DecimalDatatypeValidator.java
deleted file mode 100644
index cd7ae3b..0000000
--- a/src/org/apache/xerces/validators/datatype/DecimalDatatypeValidator.java
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Locale;
-import java.util.Vector;
-import java.io.IOException;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-import org.apache.xerces.utils.regex.RegularExpression;
-
-/**
- *
- * DecimalValidator validates that content satisfies the W3C XML Datatype for decimal
- *
- * @author Ted Leung
- * @author Jeffrey Rodriguez
- * @version $Id$
- */
-
-public class DecimalDatatypeValidator extends AbstractDatatypeValidator {
-    private Locale            fLocale           = null;
-    private DatatypeValidator fBaseValidator    = null; // Null means a native datatype
-    private boolean           fDerivedByList    = false; //Derived by restriction is defaul
-    private BigDecimal[]      fEnumDecimal      = null;
-    private String            fPattern          = null;
-    private BigDecimal        fMaxInclusive     = null;
-    private BigDecimal        fMaxExclusive     = null;
-    private BigDecimal        fMinInclusive     = null;
-    private BigDecimal        fMinExclusive     = null;
-    private int               fFacetsDefined    = 0;
-    private int               fScale            = 0;
-    private int               fPrecision        = 0;
-    private boolean           isMaxExclusiveDefined = false;
-    private boolean           isMaxInclusiveDefined = false;
-    private boolean           isMinExclusiveDefined = false;
-    private boolean           isMinInclusiveDefined = false;
-    private boolean           isScaleDefined        = false;
-    private boolean           isPrecisionDefined    = false;
-    private DatatypeMessageProvider fMessageProvider = new DatatypeMessageProvider();
-    private RegularExpression       fRegex           = null;
-    private Hashtable               fFacets          = null;
-
-
-
-    public DecimalDatatypeValidator () throws InvalidDatatypeFacetException {
-        this( null, null, false ); // Native, No Facets defined, Restriction
-    }
-
-    public DecimalDatatypeValidator ( DatatypeValidator base, Hashtable facets,
-                                      boolean derivedByList ) throws InvalidDatatypeFacetException {
-        setBasetype( base ); // Set base type 
-
-
-        fDerivedByList = derivedByList;
-
-        if ( facets != null ) {   // Set Facet
-            //fFacets = facets;
-            fFacets = checkForFacetConsistency( facets, base.getFacets() );// Check the current facets against base facets
-
-            fFacets = facets;
-            if ( fDerivedByList == false ) { // Derivation by Constraint 
-                //if( base != null ) 
-                //  System.out.println("facets = " + base.getFacets() ); 
-
-                Vector enumeration = null;
-                String value       = null;
-                for (Enumeration e = facets.keys(); e.hasMoreElements();) {
-                    String key   = (String) e.nextElement();
-                    try {
-                        if (key.equals(SchemaSymbols.ELT_PATTERN)) {
-                            value = ((String) facets.get(key ));
-                            fFacetsDefined += DatatypeValidator.FACET_PATTERN;
-                            fPattern        = value;
-                            if ( fPattern != null )
-                                fRegex = new RegularExpression(fPattern, "X" );
-                        } else if (key.equals(SchemaSymbols.ELT_ENUMERATION)) {
-                            fFacetsDefined += DatatypeValidator.FACET_ENUMERATION;
-                            enumeration     = (Vector)facets.get(key);
-                        } else if (key.equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
-                            value = ((String) facets.get(key ));
-                            fFacetsDefined += DatatypeValidator.FACET_MAXINCLUSIVE;
-                            fMaxInclusive    = new BigDecimal(stripPlusIfPresent(value));
-                        } else if (key.equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
-                            value = ((String) facets.get(key ));
-                            fFacetsDefined += DatatypeValidator.FACET_MAXEXCLUSIVE;
-                            fMaxExclusive   = new BigDecimal(stripPlusIfPresent( value));
-                        } else if (key.equals(SchemaSymbols.ELT_MININCLUSIVE)) {
-                            value = ((String) facets.get(key ));
-                            fFacetsDefined += DatatypeValidator.FACET_MININCLUSIVE;
-                            fMinInclusive   = new BigDecimal(stripPlusIfPresent(value));
-                        } else if (key.equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
-                            value = ((String) facets.get(key ));
-                            fFacetsDefined += DatatypeValidator.FACET_MINEXCLUSIVE;
-                            fMinExclusive   = new BigDecimal(stripPlusIfPresent(value));
-                        } else if (key.equals(SchemaSymbols.ELT_PRECISION)) {
-                            value = ((String) facets.get(key ));
-                            fFacetsDefined += DatatypeValidator.FACET_PRECISSION;
-                            isPrecisionDefined = true;
-                            fPrecision      = Integer.parseInt(value );
-                        } else if (key.equals(SchemaSymbols.ELT_SCALE)) {
-                            value = ((String) facets.get(key ));
-                            fFacetsDefined += DatatypeValidator.FACET_SCALE;
-                            isScaleDefined  = true;
-                            fScale          = Integer.parseInt( value );
-                        } else {
-                            throw new InvalidDatatypeFacetException(
-                                                                   getErrorString( DatatypeMessageProvider.MSG_FORMAT_FAILURE,
-                                                                                   DatatypeMessageProvider.MSG_NONE, null));
-                        }
-                    } catch ( Exception ex ){
-                        throw new InvalidDatatypeFacetException( getErrorString(
-                                                                               DatatypeMessageProvider.IllegalFacetValue, 
-                                                                               DatatypeMessageProvider.MSG_NONE, new Object [] { value, key}));
-                    }
-                }
-                isMaxExclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXEXCLUSIVE ) != 0 )?true:false;
-                isMaxInclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXINCLUSIVE ) != 0 )?true:false;
-
-                isMinExclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MINEXCLUSIVE ) != 0 )?true:false;
-                isMinInclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MININCLUSIVE ) != 0 )?true:false;
-
-                //checkForFacetConsistency( base );// Check the current facets against base facets
-
-                if ( isMaxExclusiveDefined && isMaxInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                           "It is an error for both maxInclusive and maxExclusive to be specified for the same datatype." ); 
-                }
-                if ( isMinExclusiveDefined && isMinInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                           "It is an error for both minInclusive and minExclusive to be specified for the same datatype." ); 
-                }
-
-                if ( isMaxExclusiveDefined && isMinExclusiveDefined ){
-                    int compareTo = this.fMaxExclusive.compareTo( this.fMinExclusive );
-                    if ( compareTo != 1)
-                        throw new InvalidDatatypeFacetException(
-                                                               "maxExclusive value ='" + this.fMaxExclusive + "'must be > than minExclusive value ='" + 
-                                                               this.fMinExclusive + "'. " );
-
-                }
-                if ( isMaxInclusiveDefined && isMinInclusiveDefined ){
-                    int compareTo = this.fMaxInclusive.compareTo( this.fMinInclusive );
-
-                    if ( compareTo == -1  )
-                        throw new InvalidDatatypeFacetException(
-                                                               "maxInclusive value ='" + this.fMaxInclusive + "'must be >= than minInclusive value ='" + 
-                                                               this.fMinInclusive + "'. " );
-                }
-
-
-                if ( isMaxExclusiveDefined && isMinInclusiveDefined ){
-                    int compareTo = this.fMaxExclusive.compareTo( this.fMinInclusive );
-                    if ( compareTo != 1)
-                        throw new InvalidDatatypeFacetException(
-                                                               "maxExclusive value ='" + this.fMaxExclusive + "'must be > than minInclusive value ='" + 
-                                                               this.fMinInclusive + "'. " );
-
-                }
-                if ( isMaxInclusiveDefined && isMinExclusiveDefined ){
-                    int compareTo = this.fMaxInclusive.compareTo( this.fMinExclusive );
-                    if ( compareTo != 1)
-                        throw new InvalidDatatypeFacetException(
-                                                               "maxInclusive value ='" + this.fMaxInclusive + "'must be > than minExclusive value ='" + 
-                                                               this.fMinExclusive + "'. " );
-                }
-
-
-                if ( (fFacetsDefined & DatatypeValidator.FACET_ENUMERATION ) != 0 ) {
-                    if (enumeration != null) {
-                        fEnumDecimal = new BigDecimal[enumeration.size()];
-                        int i = 0;
-                        try {
-                            for ( ; i < enumeration.size(); i++) {
-                                fEnumDecimal[i] = 
-                                new BigDecimal( stripPlusIfPresent(((String) enumeration.elementAt(i))));
-                                boundsCheck(fEnumDecimal[i]); // Check against max,min Inclusive, Exclusives
-                            }
-
-                        } catch ( Exception idve ){
-                            throw new InvalidDatatypeFacetException(
-                                                                   getErrorString(DatatypeMessageProvider.InvalidEnumValue,
-                                                                                  DatatypeMessageProvider.MSG_NONE,
-                                                                                  new Object [] { enumeration.elementAt(i)}));
-                        }
-
-                    }
-                }
-            } else { // Derivation by List
-            }
-        }//End of Facet setup
-
-    }
-
-
-    /**
-     * validate that a string matches the decimal datatype
-     *
-     * validate returns true or false depending on whether the string content is a
-     * W3C decimal type.
-     * 
-     * @param content A string containing the content to be validated
-     *                            cd 
-     * @exception throws InvalidDatatypeException if the content is
-     *  is not a W3C decimal type
-     */
-
-    public Object validate(String content, Object state) throws InvalidDatatypeValueException {
-
-        if ( fDerivedByList == false ) { //derived by restriction
-
-            if ( this.fBaseValidator != null ) {//validate against parent type if any
-                //System.out.println( "validator = " + this.fBaseValidator );
-                this.fBaseValidator.validate( content, state );
-            }
-
-
-            if ( (fFacetsDefined & DatatypeValidator.FACET_PATTERN ) != 0 ) {
-                if ( fRegex == null || fRegex.matches( content) == false )
-                    throw new InvalidDatatypeValueException("Value'"+content+
-                       "' does not match regular expression facet " + fRegex.getPattern() );
-            }
-
-            BigDecimal d = null; // Is content a Decimal 
-            try {
-                d = new BigDecimal( stripPlusIfPresent( content));
-            } catch (Exception nfe) {
-                throw new InvalidDatatypeValueException(
-                                                       getErrorString(DatatypeMessageProvider.NotDecimal,
-                                                                      DatatypeMessageProvider.MSG_NONE,
-                                                                      new Object[] { "'" + content +"'"}));
-            }
-            //} 
-            //catch (IOException ex ) {
-            //  throw new InvalidDatatypeValueException(
-            //  getErrorString(DatatypeMessageProvider.NotDecimal,
-            // DatatypeMessageProvider.MSG_NONE,
-            //                       new Object[] { "'" + content +"'"}));
-            //}
-
-
-            if ( isScaleDefined == true ) {
-                if (d.scale() > fScale)
-                    throw new InvalidDatatypeValueException(
-                                                           getErrorString(DatatypeMessageProvider.ScaleExceeded,
-                                                                          DatatypeMessageProvider.MSG_NONE,
-                                                                          new Object[] { content}));
-            }
-            if ( isPrecisionDefined == true ) {
-                int precision = d.movePointRight(d.scale()).toString().length() - 
-                                ((d.signum() < 0) ? 1 : 0); // account for minus sign
-                if (precision > fPrecision)
-                    throw new InvalidDatatypeValueException(
-                                                           getErrorString(DatatypeMessageProvider.PrecisionExceeded,
-                                                                          DatatypeMessageProvider.MSG_NONE,
-                                                                          new Object[] {content} ));
-            }
-            boundsCheck(d);
-            if (  fEnumDecimal != null )
-                enumCheck(d);
-
-
-        } else { //derivation by list Revisit
-
-        }
-        return null;
-    }
-
-    /*
-     * check that a facet is in range, assumes that facets are compatible -- compatibility ensured by setFacets
-     */
-    public void boundsCheck(BigDecimal d) throws InvalidDatatypeValueException {
-        boolean minOk = false;
-        boolean maxOk = false;
-        String  upperBound =  (fMaxExclusive != null )? ( fMaxExclusive.toString() ):
-                              ( ( fMaxInclusive != null )?fMaxInclusive.toString():"");
-
-        String  lowerBound =  (fMinExclusive != null )? ( fMinExclusive.toString() ):
-                              (( fMinInclusive != null )?fMinInclusive.toString():""); 
-        String  lowerBoundIndicator = "";
-        String  upperBoundIndicator = "";
-
-
-        if ( isMaxInclusiveDefined){
-            maxOk = (d.compareTo(fMaxInclusive) <= 0);
-            upperBound          = fMaxInclusive.toString();
-            if ( upperBound != null ){
-                upperBoundIndicator = "<="; 
-            } else {
-                upperBound="";
-            }
-        } else if ( isMaxExclusiveDefined){
-            maxOk = (d.compareTo(fMaxExclusive) < 0);
-            upperBound = fMaxExclusive.toString();
-            if ( upperBound != null ){
-                upperBoundIndicator = "<";
-            } else {
-                upperBound = "";
-            }
-        } else{
-            maxOk = (!isMaxInclusiveDefined && ! isMaxExclusiveDefined);
-        }
-
-
-        if ( isMinInclusiveDefined){
-            minOk = (d.compareTo(fMinInclusive) >= 0);
-            lowerBound = fMinInclusive.toString();
-            if( lowerBound != null ){
-            lowerBoundIndicator = "<=";
-            }else {
-                lowerBound = "";
-            }
-        } else if ( isMinExclusiveDefined){
-            minOk = (d.compareTo(fMinExclusive) > 0);
-            lowerBound = fMinExclusive.toString();
-            if( lowerBound != null ){
-            lowerBoundIndicator = "<";
-            } else {
-                lowerBound = "";
-            }
-        } else{
-            minOk = (!isMinInclusiveDefined && !isMinExclusiveDefined);
-        }
-
-        if (!(minOk && maxOk))
-            throw new InvalidDatatypeValueException (
-                                                    getErrorString(DatatypeMessageProvider.OutOfBounds,
-                                                                   DatatypeMessageProvider.MSG_NONE,
-                                                                   new Object [] { d.toString() ,  lowerBound ,
-                                                                       upperBound, lowerBoundIndicator, upperBoundIndicator}));
-
-    }
-
-    private void enumCheck(BigDecimal v) throws InvalidDatatypeValueException {
-        for (int i = 0; i < fEnumDecimal.length; i++) {
-            if (v.equals(fEnumDecimal[i] ))
-            {
-                return;
-            }
-        }
-        throw new InvalidDatatypeValueException(
-                                               getErrorString(DatatypeMessageProvider.NotAnEnumValue,
-                                                              DatatypeMessageProvider.MSG_NONE,
-                                                              new Object [] { v}));
-    }
-
-    /**
-     * set the locate to be used for error messages
-     */
-    public void setLocale(Locale locale) {
-        fLocale = locale;
-    }
-
-    public Hashtable getFacets(){
-        return fFacets;
-    }
-
-    private String getErrorString(int major, int minor, Object args[]) {
-        try {
-            return fMessageProvider.createMessage(fLocale, major, minor, args);
-        } catch (Exception e) {
-            return "Illegal Errorcode "+minor;
-        }
-    }
-    /**
-       * Returns a copy of this object.
-       */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
-    }
-
-
-    /*
-    public static void main(String args[]) {
-        // simple unit test
-        try {
-            DatatypeValidator v = new DecimalValidator();
-            Hashtable facets = new Hashtable();
-            facets.put("minInclusive","0");
-            DatatypeValidator nonneg = new DecimalValidator();
-            nonneg.setBasetype(v);
-            nonneg.setFacets(facets);
-            facets = new Hashtable();
-            facets.put("minInclusive","-1");
-            DatatypeValidator bad = new DecimalValidator();
-            bad.setBasetype(nonneg);
-            bad.setFacets(facets);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-    */
-
-    public int compare( String content1, String content2){
-        return 0;
-    }
-
-
-    private void setBasetype(DatatypeValidator base) {
-        fBaseValidator =  base;
-    }
-
-    /**
-     * This class deals with a bug in BigDecimal class
-     * present up to version 1.1.2. 1.1.3 knows how
-     * to deal with the + sign.
-     * 
-     * This method strips the first '+' if it found
-     * alone such as.
-     * +33434.344
-     * 
-     * If we find +- then nothing happens we just
-     * return the string passed
-     * 
-     * @param value
-     * @return 
-     */
-    static private String stripPlusIfPresent( String value ){
-        String strippedPlus = value;
-
-        if ( value.length() >= 2 && value.charAt(0) == '+' && value.charAt(1) != '-' ) {
-            strippedPlus = value.substring(1);
-        }
-        return strippedPlus;
-    }
-
-    /**
-     * This method checks the current Facet being set
-     * against the base Facet.
-     * Current Facet should be more restrictive than
-     * parent.
-     * Facet values are inherited from base. 
-     * 
-     * @param thisTypeFacets
-     * @param baseTypeFacets
-     * @return 
-     * @exception InvalidDatatypeFacetException
-     */
-    private Hashtable checkForFacetConsistency( Hashtable thisTypeFacets, 
-                                                Hashtable baseTypeFacets ) throws InvalidDatatypeFacetException{
-        String  thisTypeFacetValue;
-        String  baseValue;
-        if ( baseTypeFacets  != null ) {//Merge base type facets into thisType if not defined
-            Enumeration setOfBaseKeys = baseTypeFacets.keys();
-            String keyInBase;
-            BigDecimal  valueOfThisType = null;
-            BigDecimal  valueOfBase     = null;
-            while (  setOfBaseKeys.hasMoreElements() ) {
-                keyInBase          = (String) setOfBaseKeys.nextElement();
-                baseValue          = (String) baseTypeFacets.get(keyInBase);
-                thisTypeFacetValue = (String) thisTypeFacets.get(keyInBase);
-                if ( thisTypeFacetValue == null )    {
-                    String strThisType = null;
-                    thisTypeFacets.put( keyInBase, 
-                                        baseValue );
-                    if ( keyInBase.equals( SchemaSymbols.ELT_MAXEXCLUSIVE ) &&
-                         thisTypeFacets.containsKey( SchemaSymbols.ELT_MAXINCLUSIVE ) ){
-
-                        strThisType     = (String) thisTypeFacets.get( SchemaSymbols.ELT_MAXINCLUSIVE );
-                        valueOfThisType = new BigDecimal(stripPlusIfPresent(strThisType));
-                        valueOfBase     = new BigDecimal(stripPlusIfPresent( baseValue));
-                        if ( valueOfThisType.compareTo( valueOfBase) == -1 ){ 
-                            thisTypeFacets.remove( keyInBase);
-                        } else {
-                            thisTypeFacets.remove( SchemaSymbols.ELT_MAXINCLUSIVE );
-                        }
-
-                    } else if ( keyInBase.equals( SchemaSymbols.ELT_MAXINCLUSIVE ) && 
-                                thisTypeFacets.containsKey( SchemaSymbols.ELT_MAXEXCLUSIVE ) ){
-                        strThisType     = (String) thisTypeFacets.get( SchemaSymbols.ELT_MAXEXCLUSIVE );
-                        valueOfThisType = new BigDecimal(stripPlusIfPresent(strThisType));
-                        valueOfBase     = new BigDecimal(stripPlusIfPresent( baseValue));
-                        if ( valueOfThisType.compareTo( valueOfBase) == -1 ){ 
-                            thisTypeFacets.remove( keyInBase);
-                        } else {
-                            thisTypeFacets.remove( SchemaSymbols.ELT_MAXEXCLUSIVE );
-                        }
-                    } else if ( keyInBase.equals( SchemaSymbols.ELT_MINEXCLUSIVE) &&
-                                thisTypeFacets.containsKey( SchemaSymbols.ELT_MININCLUSIVE ) ){
-                        strThisType     = (String) thisTypeFacets.get( SchemaSymbols.ELT_MININCLUSIVE );
-                        valueOfThisType = new BigDecimal(stripPlusIfPresent(strThisType));
-                        valueOfBase     = new BigDecimal(stripPlusIfPresent( baseValue));
-                        if ( valueOfThisType.compareTo( valueOfBase) == 1 ){ 
-                            thisTypeFacets.remove( keyInBase);
-                        } else {
-                            thisTypeFacets.remove( SchemaSymbols.ELT_MININCLUSIVE );
-                        }
-                    } else if ( keyInBase.equals( SchemaSymbols.ELT_MININCLUSIVE ) &&
-                                thisTypeFacets.containsKey( SchemaSymbols.ELT_MINEXCLUSIVE ) ){
-                        strThisType     = (String) thisTypeFacets.get( SchemaSymbols.ELT_MINEXCLUSIVE );
-                        valueOfThisType = new BigDecimal(stripPlusIfPresent(strThisType));
-                        valueOfBase     = new BigDecimal(stripPlusIfPresent(baseValue));
-                        if ( valueOfThisType.compareTo( valueOfBase) ==  1 ){ 
-                            thisTypeFacets.remove( keyInBase);
-                        } else {
-                            thisTypeFacets.remove( SchemaSymbols.ELT_MINEXCLUSIVE );
-                        }
-
-                    }
-                    //else {
-                    //  thisTypeFacets.put( keyInBase, 
-                    //                    baseValue );//If facet is set in base type it should be set in derived type
-                    // }
-                } else{ //Check for conflicts 
-                        //Assumptions are:
-                        //   enumerations are merged
-                        //   pattern facets are not replaced so this type pattern wins
-                        //   
-
-                    if ( keyInBase.equals( SchemaSymbols.ELT_MAXEXCLUSIVE ) ){
-                        valueOfThisType = new BigDecimal(stripPlusIfPresent(thisTypeFacetValue));
-                        valueOfBase     = new BigDecimal(stripPlusIfPresent( baseValue));
-                        if ( ( valueOfThisType.compareTo( valueOfBase) ) == -1 ){ 
-                            ;
-                        } else { // should throw exception - Can not extend range of value 
-                            ;
-                        }
-                    } else if ( keyInBase.equals( SchemaSymbols.ELT_MAXINCLUSIVE ) ){
-                        valueOfThisType = new BigDecimal(stripPlusIfPresent(thisTypeFacetValue));
-                        valueOfBase     = new BigDecimal(stripPlusIfPresent( baseValue));
-                        if ( ( valueOfThisType.compareTo( valueOfBase) ) == -1 ){ 
-                            ;
-                        } else { // should throw exception - Can not extend range of value 
-                            ;
-                        }
-                    } else if ( keyInBase.equals( SchemaSymbols.ELT_MINEXCLUSIVE ) ){
-                        valueOfThisType = new BigDecimal(stripPlusIfPresent(thisTypeFacetValue));
-                        valueOfBase     = new BigDecimal(stripPlusIfPresent( baseValue));
-                        if ( ( valueOfThisType.compareTo( valueOfBase) ) == -1 ){ 
-                            ;
-                        } else { // should throw exception - Can not extend range of value 
-                            ;
-                        }
-                    } else if ( keyInBase.equals( SchemaSymbols.ELT_MININCLUSIVE ) ){
-                        valueOfThisType = new BigDecimal(stripPlusIfPresent(thisTypeFacetValue));
-                        valueOfBase     = new BigDecimal(stripPlusIfPresent( baseValue));
-                        if ( ( valueOfThisType.compareTo( valueOfBase) ) == -1 ){ 
-                            ;
-                        } else { // should throw exception - Can not extend range of value 
-                            ;
-                        }
-
-                    }
-                }
-            }
-        }
-        //Check for consistency and conflicting facets/
-        //This are the assumptions
-        //We will merge the enumeration facets
-
-        return thisTypeFacets;
-    }
-}
-
diff --git a/src/org/apache/xerces/validators/datatype/DoubleDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/DoubleDatatypeValidator.java
deleted file mode 100644
index 3c5372c..0000000
--- a/src/org/apache/xerces/validators/datatype/DoubleDatatypeValidator.java
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Locale;
-import java.util.Vector;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-import org.apache.xerces.utils.regex.RegularExpression;
-
-/**
- *
- * @author Ted Leung
- * @author Jeffrey Rodriguez
- * @version $Id$
- */
-
-public class DoubleDatatypeValidator extends AbstractDatatypeValidator {
-    private Locale            fLocale           = null;
-    private DatatypeValidator fBaseValidator    = null; // Null means a native datatype
-    private boolean           fDerivedByList = false; //Derived by restriction is defaul
-    private double[]          fEnumDoubles      = null;
-    private String            fPattern          = null;
-    private double            fMaxInclusive     = Double.MAX_VALUE;
-    private double            fMaxExclusive     = Double.MAX_VALUE;
-    private double            fMinInclusive     = Double.MIN_VALUE;
-    private double            fMinExclusive     = Double.MIN_VALUE;
-    private int               fFacetsDefined    = 0;
-
-    private boolean           isMaxExclusiveDefined = false;
-    private boolean           isMaxInclusiveDefined = false;
-    private boolean           isMinExclusiveDefined = false;
-    private boolean           isMinInclusiveDefined = false;
-    private RegularExpression      fRegex           = null;
-
-    private DatatypeMessageProvider fMessageProvider = new DatatypeMessageProvider();
-
-
-
-    public DoubleDatatypeValidator () throws InvalidDatatypeFacetException {
-        this( null, null, false ); // Native, No Facets defined, Restriction
-    }
-
-    public DoubleDatatypeValidator ( DatatypeValidator base, Hashtable facets,
-                                     boolean derivedByList ) throws InvalidDatatypeFacetException  {
-        if ( base != null )
-            setBasetype( base ); // Set base type 
-
-
-        fDerivedByList = derivedByList;
-
-        if ( facets != null ) {   // Set Facet
-            if ( fDerivedByList == false ) {
-                for (Enumeration e = facets.keys(); e.hasMoreElements();) {
-                    String key = (String) e.nextElement();
-                    if (key.equals(SchemaSymbols.ELT_PATTERN)) {
-                        fFacetsDefined += DatatypeValidator.FACET_PATTERN;
-                        fPattern = (String)facets.get(key);
-                        if ( fPattern != null )
-                            fRegex = new RegularExpression(fPattern, "X" );
-
-                    } else if (key.equals(SchemaSymbols.ELT_ENUMERATION)) {
-                        fFacetsDefined += DatatypeValidator.FACET_ENUMERATION;
-                        continue; //Treat the enumaration after this for loop
-                    } else if (key.equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXINCLUSIVE;
-                        String value = null;
-                        try {
-                            value  = ((String)facets.get(key));
-                            fMaxInclusive = Double.valueOf(value).doubleValue();
-                        } catch (NumberFormatException ex ) {
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue, 
-                                                                                   DatatypeMessageProvider.MSG_NONE, new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXEXCLUSIVE;
-                        String value = null;
-                        try {
-                            value  = ((String)facets.get(key));
-                            fMaxExclusive = Double.valueOf(value).doubleValue();
-                        } catch (NumberFormatException ex ) {
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue, 
-                                                                                   DatatypeMessageProvider.MSG_NONE, new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MININCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MININCLUSIVE;
-                        String value = null;
-                        try {
-                            value  = ((String)facets.get(key));
-                            fMinInclusive  = Double.valueOf(value).doubleValue();
-                        } catch (NumberFormatException ex ) {
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue, 
-                                                                                   DatatypeMessageProvider.MSG_NONE, new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MININCLUSIVE;
-                        String value = null;
-                        try {
-                            value  = ((String)facets.get(key));
-                            fMinExclusive  = Double.valueOf(value).doubleValue();
-                        } catch (NumberFormatException ex ) {
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue, 
-                                                                                   DatatypeMessageProvider.MSG_NONE, new Object [] { value, key}));
-                        }
-                    } else {
-                        throw new InvalidDatatypeFacetException( getErrorString(  DatatypeMessageProvider.MSG_FORMAT_FAILURE,
-                                                                                  DatatypeMessageProvider.MSG_NONE,
-                                                                                  null));
-                    }
-                }
-                isMaxExclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXEXCLUSIVE ) != 0 )?true:false;
-                isMaxInclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXINCLUSIVE ) != 0 )?true:false;
-                isMinExclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MINEXCLUSIVE ) != 0 )?true:false;
-                isMinInclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MININCLUSIVE ) != 0 )?true:false;
-
-
-                if ( isMaxExclusiveDefined && isMaxInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                           "It is an error for both maxInclusive and maxExclusive to be specified for the same datatype." ); 
-                }
-                if ( isMinExclusiveDefined && isMinInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                           "It is an error for both minInclusive and minExclusive to be specified for the same datatype." ); 
-                }
-
-
-
-                if ( (fFacetsDefined & DatatypeValidator.FACET_ENUMERATION ) != 0 ) {
-                    Vector v = (Vector) facets.get(SchemaSymbols.ELT_ENUMERATION);    
-                    if (v != null) {
-                        fEnumDoubles = new double[v.size()];
-                        for (int i = 0; i < v.size(); i++)
-                            try {
-                                fEnumDoubles[i] = Double.valueOf((String) v.elementAt(i)).doubleValue();
-                                boundsCheck(fEnumDoubles[i]); // Check against max,min Inclusive, Exclusives
-                            } catch (InvalidDatatypeValueException idve) {
-                                throw new InvalidDatatypeFacetException(
-                                                                       getErrorString(DatatypeMessageProvider.InvalidEnumValue,
-                                                                                      DatatypeMessageProvider.MSG_NONE,
-                                                                                      new Object [] { v.elementAt(i)}));
-                            } catch (NumberFormatException nfe) {
-                                System.out.println("Internal Error parsing enumerated values for real type");
-                            }
-                    }
-                }
-            } else {
-                //WORK TO DO -  Add derivation by list Double type
-            }
-        }// End of facet setting
-    }
-
-
-
-
-    /**
-     * validate that a string matches the real datatype
-     * @param content A string containing the content to be validated
-     * @exception throws InvalidDatatypeException if the content is
-     *  is not a W3C real type
-     */
-
-    public Object validate(String content, Object state) 
-    throws InvalidDatatypeValueException {
-        if ( fDerivedByList == false ) { //derived by restriction
-            if ( (fFacetsDefined & DatatypeValidator.FACET_PATTERN ) != 0 ) {
-                if ( fRegex == null || fRegex.matches( content) == false )
-                    throw new InvalidDatatypeValueException("Value'"+content+
-                                                            "does not match regular expression facet" + fPattern );
-            }
-
-
-            double d = 0.0;
-            try {
-                d = Double.valueOf(content).doubleValue();
-            } catch (NumberFormatException nfe) {
-                throw new InvalidDatatypeValueException(
-                                                       getErrorString(DatatypeMessageProvider.NotReal,
-                                                                      DatatypeMessageProvider.MSG_NONE,
-                                                                      new Object [] { content}));
-            }
-            boundsCheck(d);
-
-            if (((fFacetsDefined & DatatypeValidator.FACET_ENUMERATION ) != 0 ) )
-                enumCheck(d);
-
-        } else {
-            ;// TODO Derived by list validation
-        }
-        return null;
-    }
-
-    // Private Methods start here
-
-
-    /*
-     * check that a facet is in range, assumes that facets are compatible -- compatibility ensured by setFacets
-     */
-    private void boundsCheck(double d) throws InvalidDatatypeValueException {
-
-        boolean minOk = false;
-        boolean maxOk = false;
-        String  upperBound =  (fMaxExclusive != Double.MAX_VALUE )? (   Double.toString( fMaxExclusive)) :
-                              ( ( fMaxInclusive != Double.MAX_VALUE )? Double.toString( fMaxInclusive):"");
-
-        String  lowerBound =  (fMinExclusive != Double.MIN_VALUE )? ( Double.toString( fMinExclusive ) ):
-                              (( fMinInclusive != Double.MIN_VALUE )? Double.toString( fMinInclusive ):""); 
-        String  lowerBoundIndicator = "";
-        String  upperBoundIndicator = "";
-
-
-        if ( isMaxInclusiveDefined) {
-            maxOk = (d <= fMaxInclusive);
-            upperBound          = Double.toString( fMaxInclusive );
-            if ( upperBound != null ) {
-                upperBoundIndicator = "<="; 
-            } else {
-                upperBound="";
-            }
-        } else if ( isMaxExclusiveDefined) {
-            maxOk = (d < fMaxExclusive );
-            upperBound = Double.toString(fMaxExclusive );
-            if ( upperBound != null ) {
-                upperBoundIndicator = "<";
-            } else {
-                upperBound = "";
-            }
-        } else {
-            maxOk = (!isMaxInclusiveDefined && ! isMaxExclusiveDefined);
-        }
-
-
-
-        if ( isMinInclusiveDefined) {
-
-            minOk = (d >=  fMinInclusive );
-            lowerBound = Double.toString( fMinInclusive );
-            if ( lowerBound != null ) {
-                lowerBoundIndicator = "<=";
-            } else {
-                lowerBound = "";
-            }
-        } else if ( isMinExclusiveDefined) {
-            minOk = (d > fMinExclusive);
-            lowerBound = Double.toString( fMinExclusive  );
-            if ( lowerBound != null ) {
-                lowerBoundIndicator = "<";
-            } else {
-                lowerBound = "";
-            }
-        } else {
-            minOk = (!isMinInclusiveDefined && !isMinExclusiveDefined);
-        }
-
-        if (!(minOk && maxOk))
-            throw new InvalidDatatypeValueException (
-                             getErrorString(DatatypeMessageProvider.OutOfBounds,
-                                  DatatypeMessageProvider.MSG_NONE,
-                                      new Object [] { Double.toString(d) ,  lowerBound ,
-                                          upperBound, lowerBoundIndicator, upperBoundIndicator}));
-
-
-    }
-
-    private void enumCheck(double v) throws InvalidDatatypeValueException {
-        for (int i = 0; i < fEnumDoubles.length; i++) {
-            if (v == fEnumDoubles[i]) return;
-        }
-        throw new InvalidDatatypeValueException(
-                                               getErrorString(DatatypeMessageProvider.NotAnEnumValue,
-                                                              DatatypeMessageProvider.MSG_NONE,
-                                                              new Object [] { new Double(v)}));
-    }
-
-    /**
-     * Compare two Double datatype. Comparison is
-     * in Space value.
-     * 
-     * @param content1
-     * @param content2
-     * @return 
-     */
-    public int compare( String content1, String content2){
-        return 0;
-    }
-
-
-    /**
-     * Returns a Hashtable containing facet information.
-     * 
-     * @return 
-     */
-    public Hashtable getFacets(){
-        return null;
-    }
-    /**
-       * Returns a copy of this object.
-       */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
-    }
-
-
-
-    private String getErrorString(int major, int minor, Object args[]) {
-        try {
-            return fMessageProvider.createMessage(fLocale, major, minor, args);
-        } catch (Exception e) {
-            return "Illegal Errorcode "+minor;
-        }
-    }
-
-
-    private void setBasetype(DatatypeValidator base) {
-        fBaseValidator =  base;
-    }
-
-}
diff --git a/src/org/apache/xerces/validators/datatype/ENTITYDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/ENTITYDatatypeValidator.java
deleted file mode 100644
index 3480bdc..0000000
--- a/src/org/apache/xerces/validators/datatype/ENTITYDatatypeValidator.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.Hashtable;
-import java.util.Locale;
-import java.util.StringTokenizer;
-import org.apache.xerces.readers.DefaultEntityHandler;
-import org.apache.xerces.utils.XMLMessages;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.validators.datatype.StateMessageDatatype;
-
-
-
-/**
- * ENTITYDatatypeValidator implements the
- * DatattypeValidator interface.
- * This validator embodies the ENTITY attribute type
- * from XML1.0 recommendation.
- * The Value space of ENTITY is the set of all strings
- * that match the NCName production and have been
- * declared as an unparsed entity in a document
- * type definition.
- * The Lexical space of Entity is the set of all
- * strings that match the NCName production.
- * The value space of ENTITY is scoped to a specific
- * instance document.
- * 
- * Some caveats:
- * 
- * Because of the Xerces Architecture, where all
- * symbols are stored in a StringPool and Strings
- * are referenced by int then this datatype needs
- * to know about StringPool.
- * The first time that this datatype is invoked
- * we pass a message containing 2 references needed
- * by this validator:
- * - a reference to the DefaultEntityHandler  used
- * by the XMLValidator.
- * - a reference to the StringPool.
- * 
- * 
- * This validator extends also the XML1.0 validation
- * provided in DTD by providing "only on Schemas"
- * facet validation.
- * This validator also embodies the Derived datatype
- * ENTITIES which is an ENTITY derived by list.
- * 
- * These validators can be supplied by the application writer and may be useful as
- * standalone code as well as plugins to the validator architecture.
- * 
- * @author Jeffrey Rodriguez-
- * @version $Id$
- * @see org.apache.xerces.validators.datatype.DatatypeValidator
- * @see org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl
- * @see org.apache.xerces.validators.datatype.DatatypeValidatorFactory
- * @see org.apache.xerces.validators.common.XMLValidator
- */
-public class ENTITYDatatypeValidator extends AbstractDatatypeValidator {
-    private DatatypeValidator        fBaseValidator    = null;
-    private boolean                  fDerivedByList = false;
-    private DefaultEntityHandler     fEntityHandler    = null;
-    private StringPool               fStringPool       = null;
-
-    public  static final int         ENTITY_INITIALIZE = 0;
-
-
-    public ENTITYDatatypeValidator () throws InvalidDatatypeFacetException {
-        this( null, null, false ); // Native, No Facets defined, Restriction
-    }
-
-    public ENTITYDatatypeValidator ( DatatypeValidator base, Hashtable facets,
-                                     boolean derivedByList  ) throws InvalidDatatypeFacetException {
-
-        setBasetype( base ); // Set base type
-        fDerivedByList = derivedByList;
-    }
-
-
-    /**
-     * Checks that "content" string is valid 
-     * datatype.
-     * If invalid a Datatype validation exception is thrown.
-     * 
-     * @param content A string containing the content to be validated
-     * @param derivedBylist
-     *                Flag which is true when type
-     *                is derived by list otherwise it
-     *                it is derived by extension.
-     *                
-     * @exception throws InvalidDatatypeException if the content is
-     *                   invalid according to the rules for the validators
-     * @exception InvalidDatatypeValueException
-     * @see         org.apache.xerces.validators.datatype.InvalidDatatypeValueException
-     */
-    public Object validate(String content, Object state ) throws InvalidDatatypeValueException{
-
-        StateMessageDatatype message = (StateMessageDatatype) state;
-        int                  attValueHandle;
-
-
-        if ( message!= null && message.getDatatypeState() == ENTITYDatatypeValidator.ENTITY_INITIALIZE ){
-            Object[]   unpackMessage = (Object[] ) message.getDatatypeObject();
-
-            //System.out.println("unpackMessage = " + unpackMessage );
-
-            //System.out.println("obj1 = " + unpackMessage[0] );
-            //System.out.println("obj2 = " + unpackMessage[1] );
-
-
-            this.fEntityHandler      = (DefaultEntityHandler) unpackMessage[0];
-            this.fStringPool         = (StringPool) unpackMessage[1];
-        } else {
-
-
-            if ( this.fEntityHandler == null ) {
-                InvalidDatatypeValueException error = 
-                new InvalidDatatypeValueException( "ERROR: ENTITYDatatype Validator: Failed Initialization DefaultEntityHandler is null" );//Need Message
-                throw error;
-            }
-            if ( this.fStringPool == null ) {
-                InvalidDatatypeValueException error = 
-                new InvalidDatatypeValueException( "ERROR: ENTITYDatatype Validator: Failed Initialization StrinPool is null" );//Need Message
-                throw error;
-            }
-
-
-            if ( this.fDerivedByList == false ){
-
-                attValueHandle = this.fStringPool.addSymbol( content );
-                if (!this.fEntityHandler.isUnparsedEntity( attValueHandle ) ) {
-                    InvalidDatatypeValueException error = 
-                    new InvalidDatatypeValueException( "ENTITY '"+ content +"' is not valid" );//Need Message
-                    error.setMinorCode(XMLMessages.MSG_ENTITY_INVALID );
-                    error.setMajorCode(XMLMessages.VC_ENTITY_NAME);
-                    throw error;
-                }
-            } else {
-                StringTokenizer listOfEntities = new StringTokenizer(content);
-                StringBuffer sb = new StringBuffer(content.length());
-                boolean ok = true;
-                if (listOfEntities.hasMoreTokens()) {
-                    while (true) {
-                        String nextEntity = listOfEntities.nextToken();
-
-                        // ENTITIES - check that each value is an unparsed entity name (V_TAGa)
-
-                        if ( this.fEntityHandler.isUnparsedEntity(this.fStringPool.addSymbol(nextEntity) ) == false ) {
-                            ok = false;
-                        }
-                        sb.append(nextEntity);
-                        if (!listOfEntities.hasMoreTokens()) {
-                            break;
-                        }
-                        sb.append(' ');
-                    }
-                }
-                String errorContent = sb.toString();
-                if (!ok || errorContent.length() == 0) {
-                    InvalidDatatypeValueException error = 
-                    new InvalidDatatypeValueException( errorContent );
-                    error.setMinorCode(XMLMessages.MSG_ENTITIES_INVALID );
-                    error.setMajorCode(XMLMessages.VC_ENTITY_NAME);
-                    throw error;
-                }
-
-            }
-        }
-        return null;
-    }
-
-    /**
-     * REVISIT
-     * Compares two Datatype for order
-     * 
-     * @return 
-     */
-    public int compare( String  content1, String content2){
-        return -1;
-    }
-
-    public Hashtable getFacets(){
-        return null;
-    }
-
-    // Private methods start here
-
-    /**
-       * Returns a copy of this object.
-       */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
-    }
-
-
-    /**
-     * 
-     * @param base   the validator for this type's base type
-     */
-    private void setBasetype(DatatypeValidator base){
-        fBaseValidator = base;
-    }
-
-
-
-}
diff --git a/src/org/apache/xerces/validators/datatype/FloatDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/FloatDatatypeValidator.java
deleted file mode 100644
index e975fb5..0000000
--- a/src/org/apache/xerces/validators/datatype/FloatDatatypeValidator.java
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Locale;
-import java.util.Vector;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-import org.apache.xerces.utils.regex.RegularExpression;
-import java.util.StringTokenizer;
-import java.util.NoSuchElementException;
-
-/**
- *
- * @author Ted Leung
- * @author Jeffrey Rodriguez
- * @version  $Id$
- */
-
-public class FloatDatatypeValidator extends AbstractDatatypeValidator {
-    private Locale    fLocale               = null;
-    private DatatypeValidator    fBaseValidator = null; // null means a native datatype
-    private float[]   fEnumFloats           = null;
-    private String    fPattern              = null;
-    private boolean   fDerivedByList     = false; // Default is restriction
-    private float     fMaxInclusive         = Float.MAX_VALUE;
-    private float     fMaxExclusive         = Float.MAX_VALUE;
-    private float     fMinInclusive         = Float.MIN_VALUE;
-    private float     fMinExclusive         = Float.MIN_VALUE;
-    private int       fFacetsDefined        = 0;
-
-    private boolean   isMaxExclusiveDefined = false;
-    private boolean   isMaxInclusiveDefined = false;
-    private boolean   isMinExclusiveDefined = false;
-    private boolean   isMinInclusiveDefined = false;
-    private DatatypeMessageProvider fMessageProvider = new DatatypeMessageProvider();
-    private RegularExpression      fRegex    = null;
-
-
-
-    public FloatDatatypeValidator () throws InvalidDatatypeFacetException{
-        this( null, null, false ); // Native, No Facets defined, Restriction
-    }
-
-    public FloatDatatypeValidator ( DatatypeValidator base, Hashtable facets, 
-                                    boolean derivedByList ) throws InvalidDatatypeFacetException {
-        if ( base != null )
-            setBasetype( base ); // Set base type 
-
-        fDerivedByList = derivedByList; 
-        // Set Facets if any defined
-
-        if ( facets != null  )  {
-            if ( fDerivedByList == false ) {
-                for (Enumeration e = facets.keys(); e.hasMoreElements();) {
-                    String key = (String) e.nextElement();
-
-                    if (key.equals(SchemaSymbols.ELT_PATTERN)) {
-                        fFacetsDefined += DatatypeValidator.FACET_PATTERN;
-                        fPattern = (String)facets.get(key);
-                        if ( fPattern != null )
-                            fRegex = new RegularExpression(fPattern, "X" );
-
-
-                    } else if (key.equals(SchemaSymbols.ELT_ENUMERATION)) {
-                        fFacetsDefined += DatatypeValidator.FACET_ENUMERATION;
-                        continue; //Treat the enumaration after this for loop
-                    } else if (key.equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXINCLUSIVE;
-                        String value = null;
-                        try {
-                            value  = ((String)facets.get(key));
-                            fMaxInclusive = Float.valueOf(value).floatValue();
-                        } catch (NumberFormatException ex ) {
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue, 
-                                                                                   DatatypeMessageProvider.MSG_NONE, new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXEXCLUSIVE;
-                        String value = null;
-                        try {
-                            value  = ((String)facets.get(key));
-                            fMaxExclusive = Float.valueOf(value).floatValue();
-                        } catch (NumberFormatException ex ) {
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue, 
-                                                                                   DatatypeMessageProvider.MSG_NONE, new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MININCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MININCLUSIVE;
-                        String value = null;
-                        try {
-                            value  = ((String)facets.get(key));
-                            fMinInclusive  = Float.valueOf(value).floatValue();
-                        } catch (NumberFormatException ex ) {
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue, 
-                                                                                   DatatypeMessageProvider.MSG_NONE, new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MININCLUSIVE;
-                        String value = null;
-                        try {
-                            value  = ((String)facets.get(key));
-                            fMinExclusive  = Float.valueOf(value).floatValue();
-                        } catch (NumberFormatException ex ) {
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue, 
-                                                                                   DatatypeMessageProvider.MSG_NONE, new Object [] { value, key}));
-                        }
-                    } else {
-                        throw new InvalidDatatypeFacetException( getErrorString(  DatatypeMessageProvider.MSG_FORMAT_FAILURE,
-                                                                                  DatatypeMessageProvider.MSG_NONE,
-                                                                                  null));
-                    }
-                }
-                isMaxExclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXEXCLUSIVE ) != 0 )?true:false;
-                isMaxInclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXINCLUSIVE ) != 0 )?true:false;
-                isMinExclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MINEXCLUSIVE ) != 0 )?true:false;
-                isMinInclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MININCLUSIVE ) != 0 )?true:false;
-
-
-                if ( isMaxExclusiveDefined && isMaxInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                           "It is an error for both maxInclusive and maxExclusive to be specified for the same datatype." ); 
-                }
-                if ( isMinExclusiveDefined && isMinInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                           "It is an error for both minInclusive and minExclusive to be specified for the same datatype." ); 
-                }
-
-
-
-                if ( (fFacetsDefined & DatatypeValidator.FACET_ENUMERATION ) != 0 ) {
-                    Vector v = (Vector) facets.get(SchemaSymbols.ELT_ENUMERATION);    
-                    if (v != null) {
-                        fEnumFloats = new float[v.size()];
-                        for (int i = 0; i < v.size(); i++)
-                            try {
-                                fEnumFloats[i] = Float.valueOf((String) v.elementAt(i)).floatValue();
-                                boundsCheck(fEnumFloats[i]); // Check against max,min Inclusive, Exclusives
-                            } catch (InvalidDatatypeValueException idve) {
-                                throw new InvalidDatatypeFacetException(
-                                                                       getErrorString(DatatypeMessageProvider.InvalidEnumValue,
-                                                                                      DatatypeMessageProvider.MSG_NONE,
-                                                                                      new Object [] { v.elementAt(i)}));
-                            } catch (NumberFormatException nfe) {
-                                System.out.println("Internal Error parsing enumerated values for real type");
-                            }
-                    }
-                }
-            } else { //derivation by list  - WORK TO DO
-                //System.out.println( "inside derive by list" );
-
-            }
-        }// End facet setup
-    }
-
-
-    /**
-     * validate that a string matches the real datatype
-     * @param content A string containing the content to be validated
-     * @exception throws InvalidDatatypeException if the content is
-     *  is not a W3C real type
-     */
-
-    public Object validate(String content, Object state) 
-    throws InvalidDatatypeValueException {
-        if ( fDerivedByList == false  ) {
-            checkContent(  content );
-        } else {
-           StringTokenizer parsedList = new StringTokenizer( content );
-           try {
-               while ( parsedList.hasMoreTokens() ) {
-                   checkContent( parsedList.nextToken() );
-               }
-           } catch ( NoSuchElementException e ) {
-               e.printStackTrace();
-           }
-        }
-        return null;
-    }
-
-    /*
-     * check that a facet is in range, assumes that facets are compatible -- compatibility ensured by setFacets
-     */
-    private void boundsCheck(float d) throws InvalidDatatypeValueException {
-
-        boolean minOk = false;
-        boolean maxOk = false;
-        String  upperBound =  (fMaxExclusive != Float.MAX_VALUE )? (   Float.toString( fMaxExclusive)) :
-                              ( ( fMaxInclusive != Float.MAX_VALUE )? Float.toString( fMaxInclusive):"");
-
-        String  lowerBound =  (fMinExclusive != Float.MIN_VALUE )? ( Float.toString( fMinExclusive ) ):
-                              (( fMinInclusive != Float.MIN_VALUE )? Float.toString( fMinInclusive ):""); 
-        String  lowerBoundIndicator = "";
-        String  upperBoundIndicator = "";
-
-
-        if ( isMaxInclusiveDefined) {
-            maxOk = (d <= fMaxInclusive);
-            upperBound          = Float.toString( fMaxInclusive );
-            if ( upperBound != null ) {
-                upperBoundIndicator = "<="; 
-            } else {
-                upperBound="";
-            }
-        } else if ( isMaxExclusiveDefined) {
-            maxOk = (d < fMaxExclusive );
-            upperBound = Float.toString(fMaxExclusive );
-            if ( upperBound != null ) {
-                upperBoundIndicator = "<";
-            } else {
-                upperBound = "";
-            }
-        } else {
-            maxOk = (!isMaxInclusiveDefined && ! isMaxExclusiveDefined);
-        }
-
-
-
-        if ( isMinInclusiveDefined) {
-
-            minOk = (d >=  fMinInclusive );
-            lowerBound = Float.toString( fMinInclusive );
-            if ( lowerBound != null ) {
-                lowerBoundIndicator = "<=";
-            } else {
-                lowerBound = "";
-            }
-        } else if ( isMinExclusiveDefined) {
-            minOk = (d > fMinExclusive);
-            lowerBound = Float.toString( fMinExclusive  );
-            if ( lowerBound != null ) {
-                lowerBoundIndicator = "<";
-            } else {
-                lowerBound = "";
-            }
-        } else {
-            minOk = (!isMinInclusiveDefined && !isMinExclusiveDefined);
-        }
-
-        if (!(minOk && maxOk))
-            throw new InvalidDatatypeValueException (
-                             getErrorString(DatatypeMessageProvider.OutOfBounds,
-                                  DatatypeMessageProvider.MSG_NONE,
-                                      new Object [] { Float.toString(d) ,  lowerBound ,
-                                          upperBound, lowerBoundIndicator, upperBoundIndicator}));
-
-    }
-
-    private void enumCheck(float v) throws InvalidDatatypeValueException {
-        for (int i = 0; i < fEnumFloats.length; i++) {
-            if (v == fEnumFloats[i]) return;
-        }
-        throw new InvalidDatatypeValueException(
-                                               getErrorString(DatatypeMessageProvider.NotAnEnumValue,
-                                                              DatatypeMessageProvider.MSG_NONE,
-                                                              new Object [] { new Float(v)}));
-    }
-
-    /**
-     * set the locate to be used for error messages
-     */
-    public void setLocale(Locale locale) {
-        fLocale = locale;
-    }
-
-    public int compare( String content1, String content2){
-        return 0;
-    }
-
-
-    
-
-
-
-    public Hashtable getFacets(){
-        return null;
-    }
-    /**
-       * Returns a copy of this object.
-       */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
-    }
-
-
-    private String getErrorString(int major, int minor, Object args[]) {
-        try {
-            return fMessageProvider.createMessage(fLocale, major, minor, args);
-        } catch (Exception e) {
-            return "Illegal Errorcode "+minor;
-        }
-    }
-
-
-    private void setBasetype(DatatypeValidator base) {
-        fBaseValidator =  base;
-    }
-
-    private  void checkContent( String content )throws InvalidDatatypeValueException {
-        if ( (fFacetsDefined & DatatypeValidator.FACET_PATTERN ) != 0 ) {
-                if ( fRegex == null || fRegex.matches( content) == false )
-                    throw new InvalidDatatypeValueException("Value'"+content+
-                                                            "does not match regular expression facet" + fPattern );
-            }
-
-
-            float f = 0;
-            try {
-                //System.out.println("content = " + content );
-                f = Float.valueOf(content).floatValue();
-                //System.out.println("f = " + f );
-            } catch (NumberFormatException nfe) {
-                if( content.equals("INF") ){
-                    f=Float.POSITIVE_INFINITY;
-                } else if( content.equals("-INF") ){
-                    f=Float.NEGATIVE_INFINITY;
-                } else if( content.equals("NaN" ) ) {
-                    f=Float.NaN;
-                } else {
-                    throw new InvalidDatatypeValueException(
-                                  getErrorString(DatatypeMessageProvider.NotFloat,
-                                                 DatatypeMessageProvider.MSG_NONE,
-                                                           new Object [] { content}));
-                }
-            }
-            boundsCheck(f);
-
-            if (((fFacetsDefined & DatatypeValidator.FACET_ENUMERATION ) != 0 ) )
-                enumCheck(f);
-
-    }
-
-}
diff --git a/src/org/apache/xerces/validators/datatype/IDDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/IDDatatypeValidator.java
deleted file mode 100644
index fff6820..0000000
--- a/src/org/apache/xerces/validators/datatype/IDDatatypeValidator.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.Hashtable;
-import java.util.Locale;
-import org.apache.xerces.utils.XMLCharacterProperties;
-import org.apache.xerces.utils.XMLMessages;
-
-/**
- * DataTypeValidator defines the interface that data type validators must obey.
- * These validators can be supplied by the application writer and may be useful as
- * standalone code as well as plugins to the validator architecture.
- * @author Jeffrey Rodriguez
- * @version $Id$
- */
-public class IDDatatypeValidator extends AbstractDatatypeValidator {
-    private DatatypeValidator         fBaseValidator = null;
-    private boolean                   fDerivedByList = false;
-    private Object                        fNullValue = null;
-    private DatatypeMessageProvider fMessageProvider = new DatatypeMessageProvider();
-    private Hashtable                     fTableOfId;
-    private Locale                 fLocale           = null;
-    public static final  int          IDREF_STORE    = 0;
-    public static final  int          ID_CLEAR       = 1;
-
-
-
-    public IDDatatypeValidator () throws InvalidDatatypeFacetException {
-        this( null, null, false ); // Native, No Facets defined, Restriction
-    }
-
-    public IDDatatypeValidator ( DatatypeValidator base, Hashtable facets, 
-                                 boolean derivedByList ) throws InvalidDatatypeFacetException  {
-        fDerivedByList = derivedByList;
-    }
-
-
-
-    /**
-     * Checks that "content" string is valid
-     * datatype.
-     * If invalid a Datatype validation exception is thrown.
-     * 
-     * @param content A string containing the content to be validated
-     * @param state  Generic Object state that can be use to pass
-     *               Structures
-     * @return 
-     * @exception throws InvalidDatatypeException if the content is
-     *                   invalid according to the rules for the validators
-     * @exception InvalidDatatypeValueException
-     * @see org.apache.xerces.validators.datatype.InvalidDatatypeValueException
-     */
-    public Object validate(String content, Object IDStorage ) throws InvalidDatatypeValueException{
-
-        StateMessageDatatype message;
-        if ( this.fDerivedByList == false ){
-            if (IDStorage != null ){
-                //System.out.println("We received reset" );
-                message = (StateMessageDatatype) IDStorage;    
-                if (message.getDatatypeState() == IDDatatypeValidator.ID_CLEAR ){
-                    if ( this.fTableOfId  != null ){
-                        this.fTableOfId.clear(); //Clean the ID Hash Table see the XMLValidator pool reset method
-                        this.fTableOfId = null;
-                    }
-                    return null;
-                }
-            }
-            if (!XMLCharacterProperties.validName(content)) {//Check if is valid key-[81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
-                InvalidDatatypeValueException error =  new
-                                                       InvalidDatatypeValueException( "ID is not valid: " + content );
-                error.setMinorCode(XMLMessages.MSG_ID_INVALID);
-                error.setMajorCode(XMLMessages.VC_ID);
-                throw error;
-            }
-
-            if (!addId( content, IDStorage) ){ //It is OK to pass a null here
-                InvalidDatatypeValueException error = 
-                new InvalidDatatypeValueException( "ID '" + content +"'  has to be unique" );
-                error.setMinorCode(XMLMessages.MSG_ID_NOT_UNIQUE);
-                error.setMajorCode(XMLMessages.VC_ID);
-                throw error;
-            }
-        } else{ //Need to revisit case when derived by list
-
-        }
-        //System.out.println("IDStorage = " + IDStorage );
-        //System.out.println("Bef return = " + fTableOfId );
-        return fTableOfId;//Return the table of Id
-    }
-
-    /**
-     * REVISIT
-     * Compares two Datatype for order
-     * 
-     * @param o1
-     * @param o2
-     * @return 
-     */
-    public int compare( String content1, String content2){
-        return -1;
-    }
-
-    public Hashtable getFacets(){
-        return null;
-    }
-
-    /**
-       * Returns a copy of this object.
-       */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
-    }
-
-
-    /**
-     * Name of base type as a string.
-     * A Native datatype has the string "native"  as its
-     * base type.
-     * 
-     * @param base   the validator for this type's base type
-     */
-    private void setBasetype(DatatypeValidator base){
-        fBaseValidator = base;
-    }
-
-    /** addId. */
-    private boolean addId(String content, Object idTable) {
-
-        //System.out.println("Added ID = " + content );
-        if ( this.fTableOfId == null ) {
-            //System.out.println("Create table");
-            this.fTableOfId = new Hashtable();//Gain reference to table
-        } else if ( this.fTableOfId.containsKey( content ) ){ 
-            //System.out.println("ID - it already has this key =" + content +"table = " + this.fTableOfId  );
-            return false;
-        }
-        if ( this.fNullValue == null ){
-            fNullValue = new Object();
-        }
-        //System.out.println("Before putting content" + content );
-        try {
-            this.fTableOfId.put( content, fNullValue ); 
-        } catch ( Exception ex ){
-            ex.printStackTrace();
-        }
-        return true;
-    } // addId(int):boolean
-
-
-    /**
-     * set the locate to be used for error messages
-     */
-    public void setLocale(Locale locale) {
-        fLocale = locale;
-    }
-
-
-    private String getErrorString(int major, int minor, Object args[]) {
-        try {
-            return fMessageProvider.createMessage(fLocale, major, minor, args);
-        } catch (Exception e) {
-            return "Illegal Errorcode "+minor;
-        }
-    }
-
-
-}
diff --git a/src/org/apache/xerces/validators/datatype/IDREFDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/IDREFDatatypeValidator.java
deleted file mode 100644
index f423165..0000000
--- a/src/org/apache/xerces/validators/datatype/IDREFDatatypeValidator.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.Hashtable;
-import java.util.Locale;
-import java.util.Enumeration;
-import java.util.StringTokenizer;
-import org.apache.xerces.utils.XMLCharacterProperties;
-import org.apache.xerces.utils.XMLMessages;
-
-
-
-
-
-/**
- * IDREFValidator defines the interface that data type validators must obey.
- * These validators can be supplied by the application writer and may be useful as
- * standalone code as well as plugins to the validator architecture.
- * 
- * @author Jeffrey Rodriguez-
- * @version $Id$
- */
-public class IDREFDatatypeValidator extends AbstractDatatypeValidator {
-    private DatatypeValidator fBaseValidator    = null;
-    private boolean           fDerivedByList    = false;
-    private Hashtable              fTableOfId   = null; //This is pass to us through the state object
-    private Hashtable              fTableIDRefs = null;
-    private Object                   fNullValue = null;
-    private Locale            fLocale           = null;
-    private DatatypeMessageProvider fMessageProvider = new DatatypeMessageProvider();
-
-    public static final  int       IDREF_STORE    = 0;
-    public static final  int       IDREF_CLEAR    = 1;
-    public static final  int       IDREF_VALIDATE = 2; 
-
-
-
-    public IDREFDatatypeValidator () throws InvalidDatatypeFacetException {
-        this( null, null, false ); // Native, No Facets defined, Restriction
-    }
-
-    public IDREFDatatypeValidator ( DatatypeValidator base, Hashtable facets, 
-                                    boolean derivedByList ) throws InvalidDatatypeFacetException { 
-
-        fDerivedByList = derivedByList;
-        setBasetype( base ); // Set base type 
-
-    }
-
-
-    /**
-     * Checks that "content" string is valid 
-     * datatype.
-     * If invalid a Datatype validation exception is thrown.
-     * 
-     * @param content A string containing the content to be validated
-     * @param derivedBylist
-     *                Flag which is true when type
-     *                is derived by list otherwise it
-     *                it is derived by extension.
-     *                
-     * @exception throws InvalidDatatypeException if the content is
-     *                   invalid according to the rules for the validators
-     * @exception InvalidDatatypeValueException
-     * @see         org.apache.xerces.validators.datatype.InvalidDatatypeValueException
-     */
-    public Object validate(String content, Object state ) throws InvalidDatatypeValueException{
-        //Pass content as a String
-        //System.out.println( "base = " + this.fBaseValidator );
-
-        //if( this.fBaseValidator != null ){
-          //  this.fBaseValidator.validate( content, state );
-        //}
-        StateMessageDatatype message;
-        if ( this.fDerivedByList == false ){
-            //System.out.println("conten = " + content );
-            if (state!= null){
-                message = (StateMessageDatatype) state;    
-                if (message.getDatatypeState() == IDREFDatatypeValidator.IDREF_CLEAR ){
-                    if ( this.fTableOfId != null ){
-                        fTableOfId.clear(); //This is pass to us through the state object
-                    }
-                    if ( this.fTableIDRefs != null ){
-                        fTableIDRefs.clear(); 
-                    }
-                    return null;
-                } else if ( message.getDatatypeState() == IDREFDatatypeValidator.IDREF_VALIDATE ){
-                    this.checkIdRefs();//Validate that all keyRef is a keyIds
-                } else if ( message.getDatatypeState() == IDREFDatatypeValidator.IDREF_STORE ) {
-                    this.fTableOfId = (Hashtable) message.getDatatypeObject();
-                    if (!XMLCharacterProperties.validName(content)) {//Check if is valid key
-
-                        InvalidDatatypeValueException error = new InvalidDatatypeValueException( "IDREF is not valid" );//Need Message
-
-                        error.setMinorCode(XMLMessages.MSG_IDREF_INVALID );
-                        error.setMajorCode(XMLMessages.VC_IDREF);
-                        throw error;//Need Message
-                    }
-                    //System.out.println("Content REF = " + content );
-                    addIdRef( content, state);// We are storing IDs 
-                }
-            }
-         } else {
-            //System.out.println("list = " + content );
-            if (state!= null){
-                message = (StateMessageDatatype) state;    
-                if (message.getDatatypeState() == IDREFDatatypeValidator.IDREF_CLEAR ){
-                    if ( this.fTableOfId != null ){
-                        fTableOfId.clear(); //This is pass to us through the state object
-                    }
-                    if ( this.fTableIDRefs != null ){
-                        fTableIDRefs.clear(); 
-                    }
-                    return null;
-
-                } else if ( message.getDatatypeState() == IDREFDatatypeValidator.IDREF_VALIDATE ){
-                    //System.out.println("Call to Validate IDREFS" );
-                    this.checkIdRefs();//Validate that all keyRef is a keyIds
-                } else if ( message.getDatatypeState() == IDREFDatatypeValidator.IDREF_STORE ) {
-                    //System.out.println("IDREFS = " + content );
-                    StringTokenizer   tokenizer = new StringTokenizer( content );
-                    this.fTableOfId = (Hashtable) message.getDatatypeObject();
-                    while ( tokenizer.hasMoreTokens() ) {
-                        String idName = tokenizer.nextToken(); 
-                        //System.out.println("idName here = " + idName );
-                        if( this.fBaseValidator != null ){
-                               this.fBaseValidator.validate( idName, state );
-                        }
-                        addIdRef( idName, state);// We are storing IDs 
-                    }
-                }
-
-            }
-
-        }
-        return null;
-    }
-
-
-    /**
-     * REVISIT
-     * Compares two Datatype for order
-     * 
-     * @param o1
-     * @param o2
-     * @return 
-     */
-    public int compare( String content1, String content2){
-        return -1;
-    }
-
-
-    public Hashtable getFacets(){
-        return null;
-    }
-    /**
-       * Returns a copy of this object.
-       */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
-    }
-
-    /**
-      * Name of base type as a string.
-      * A Native datatype has the string "native"  as its
-      * base type.
-      * 
-      * @param base   the validator for this type's base type
-      */
-    private void setBasetype(DatatypeValidator base){
-        fBaseValidator = base;
-    }
-
-    /** addId. */
-    private void addIdRef(String content, Object state) {
-        //System.out.println("this.fTableOfId = " + content );
-        //System.out.println("state =  " + state  );
-        //System.out.println("table = " + this.fTableOfId );
-
-
-        if ( this.fTableOfId != null &&  this.fTableOfId.containsKey( content ) ){
-            //System.out.println("It already contains key = " + content );
-            return;
-        }
-        //System.out.println("Table of IDRefs = " + this.fTableIDRefs );
-        if ( this.fTableIDRefs == null ){
-            this.fTableIDRefs = new Hashtable();
-        } else if ( fTableIDRefs.containsKey( content ) ){
-            return;
-        }
-
-
-        if ( this.fNullValue == null ){
-            fNullValue = new Object();
-        }
-        //System.out.println("tabl IDREFs = " + this.fTableIDRefs );
-        try {
-            this.fTableIDRefs.put( content, fNullValue ); 
-        } catch( OutOfMemoryError ex ){
-            System.out.println( "Out of Memory: Hashtable of ID's has " + this.fTableIDRefs.size() + " Elements" );
-            ex.printStackTrace();
-        }
-    } // addId(int):boolean
-
-
-    private void checkIdRefs() throws InvalidDatatypeValueException {
-
-        if ( this.fTableIDRefs == null)
-            return;
-        
-        Enumeration en = this.fTableIDRefs.keys();
-        //System.out.println("TabIDREFs=  " + this.fTableIDRefs );
-
-        while (en.hasMoreElements()) {
-            String key = (String)en.nextElement();
-            //System.out.println( "Key here = x>>" + key + "<<" );
-            //System.out.println("Tab Ids = " + this.fTableOfId );
-            if ( this.fTableOfId == null || ! this.fTableOfId.containsKey(key)) {
-                
-                InvalidDatatypeValueException error =  new
-                            InvalidDatatypeValueException( key );
-                error.setMinorCode(XMLMessages.MSG_ELEMENT_WITH_ID_REQUIRED);
-                error.setMajorCode(XMLMessages.VC_IDREF);
-                throw error;
-            }
-        }
-
-    } // checkIdRefs()
-
-
-    /**
-    * set the locate to be used for error messages
-    */
-    public void setLocale(Locale locale) {
-        fLocale = locale;
-    }
-
-
-    private String getErrorString(int major, int minor, Object args[]) {
-        try {
-            return fMessageProvider.createMessage(fLocale, major, minor, args);
-        } catch (Exception e) {
-            return "Illegal Errorcode "+minor;
-        }
-    }
-
-
-}
-
diff --git a/src/org/apache/xerces/validators/datatype/InvalidDatatypeFacetException.java b/src/org/apache/xerces/validators/datatype/InvalidDatatypeFacetException.java
deleted file mode 100644
index 3fde1ee..0000000
--- a/src/org/apache/xerces/validators/datatype/InvalidDatatypeFacetException.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xerces.validators.datatype;
-
-
-
-/**
- * 
- * @author Jeffrey Rodriguez
- * @version $Id$
- */
-public class InvalidDatatypeFacetException extends XMLException {
-    private int majorCode = -1;
-    private int minorCode  = -1;
-
-    public  int getMinorCode(){
-      return  minorCode;
-    }
-    public  int getMajorCode(){
-      return  majorCode;
-    }
-
-    public  void setMinorCode(int code ){
-      majorCode = code;
-    }
-    public  void setMajorCode(int code ){
-      minorCode = code;
-    }
-
-    public InvalidDatatypeFacetException ( ){ 
-        super();
-    }
-    public InvalidDatatypeFacetException ( String message ) {
-        super( message );
-    }
-    public InvalidDatatypeFacetException ( Exception exception ) {
-        super( exception );
-    }
-    public InvalidDatatypeFacetException ( String message, Exception exception ) {
-        super( message, exception );
-    }
-}
diff --git a/src/org/apache/xerces/validators/datatype/InvalidDatatypeValueException.java b/src/org/apache/xerces/validators/datatype/InvalidDatatypeValueException.java
deleted file mode 100644
index 3775916..0000000
--- a/src/org/apache/xerces/validators/datatype/InvalidDatatypeValueException.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
- 
-package org.apache.xerces.validators.datatype;
-
-/**
- * InvalidDatatypeValueException is thrown when data value doesn't match it's datatype
- * 
- * @author Jeffrey Rodriguez
- * @version $Id$
- */
-public class InvalidDatatypeValueException extends XMLException {
-    private int majorCode = -1;
-    private int minorCode  = -1;
-
-    public  int getMinorCode(){
-        return  minorCode;
-    }
-    public  int getMajorCode(){
-        return  majorCode;
-    }
-
-    public  void setMinorCode(int code ){
-        majorCode = code;
-    }
-    public  void setMajorCode(int code ){
-        minorCode = code;
-    }
-
-    public  InvalidDatatypeValueException() { super(); }
-    public  InvalidDatatypeValueException(String msg) { super(msg); }
-    public  InvalidDatatypeValueException ( Exception exception ) {
-        super( exception );
-    }
-    public InvalidDatatypeValueException ( String message, Exception exception ) {
-        super( message, exception );
-    }
-}
diff --git a/src/org/apache/xerces/validators/datatype/Makefile b/src/org/apache/xerces/validators/datatype/Makefile
deleted file mode 100644
index 9c04f7e..0000000
--- a/src/org/apache/xerces/validators/datatype/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-# Makefile for directory ./org/apache/xerces/validators/datatype
-
-TARGETS=\
-	AbstractDatatypeValidator.class\
-	BinaryDatatypeValidator.class\
-	BooleanDatatypeValidator.class\
-	DatatypeMessageProvider.class\
-	DatatypeValidator.class\
-	DatatypeValidatorFactory.class\
-	DecimalDatatypeValidator.class\
-	DoubleDatatypeValidator.class\
-	ENTITYDatatypeValidator.class \
-	FloatDatatypeValidator.class\
-	IDDatatypeValidator.class \
-	IDREFDatatypeValidator.class \
-	InvalidDatatypeFacetException.class\
-	InvalidDatatypeValueException.class\
-	NOTATIONDatatypeValidator.class \
-	QNameDatatypeValidator.class\
-	StringDatatypeValidator.class\
-	URIReferenceDatatypeValidator.class \
-	RecurringDurationDatatypeValidator.class\
-	TimeDurationDatatypeValidator.class\
-	DatatypeValidatorFactoryImpl.class\
-	StateMessageDatatype.class\
-	XMLException.class 
-
-DIRS = 
-
-TOP = ../../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xerces/validators/datatype/NOTATIONDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/NOTATIONDatatypeValidator.java
deleted file mode 100644
index e5043b0..0000000
--- a/src/org/apache/xerces/validators/datatype/NOTATIONDatatypeValidator.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.Hashtable;
-import java.util.Locale;
-
-/**
- * NOTATIONValidator defines the interface that data type validators must obey.
- * These validators can be supplied by the application writer and may be useful as
- * standalone code as well as plugins to the validator architecture.
- * 
- * @author Jeffrey Rodriguez-
- * @version $Id$
- */
-public class NOTATIONDatatypeValidator extends AbstractDatatypeValidator {
-    private DatatypeValidator fBaseValidator = null;
-    private boolean   fDerivedByList     = false; // Default is
-
-    public NOTATIONDatatypeValidator () throws InvalidDatatypeFacetException {
-        this( null, null, false ); // Native, No Facets defined, Restriction
-    }
-
-    public NOTATIONDatatypeValidator ( DatatypeValidator base, Hashtable facets, 
-         boolean derivedByList ) throws InvalidDatatypeFacetException {
-         fDerivedByList = derivedByList;
-         setBasetype( base ); // Set base type 
-    }
-
-
-    /**
-     * Checks that "content" string is valid 
-     * datatype.
-     * If invalid a Datatype validation exception is thrown.
-     * 
-     * @param content A string containing the content to be validated
-     * @param derivedBylist
-     *                Flag which is true when type
-     *                is derived by list otherwise it
-     *                it is derived by extension.
-     *                
-     * @exception throws InvalidDatatypeException if the content is
-     *                   invalid according to the rules for the validators
-     * @exception InvalidDatatypeValueException
-     * @see         org.apache.xerces.validators.datatype.InvalidDatatypeValueException
-     */
-    public Object validate(String content, Object state ) throws InvalidDatatypeValueException{
-        return null;
-    }
-
-    public Hashtable getFacets(){
-        return null;
-    }
-
-
-
-    /**
-    * set the locate to be used for error messages
-    */
-    public void setLocale(Locale locale){
-    }
-
-    /**
-     * REVISIT
-     * Compares two Datatype for order
-     * 
-     * @param o1
-     * @param o2
-     * @return 
-     */
-    public int compare( String content1, String content2){
-        return -1;
-    }
-  /**
-     * Returns a copy of this object.
-     */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
-    }
-
-    /**
-     * Name of base type as a string.
-     * A Native datatype has the string "native"  as its
-     * base type.
-     * 
-     * @param base   the validator for this type's base type
-     */
-
-    private void setBasetype(DatatypeValidator base){
-        fBaseValidator = base;
-    }
-
-
-}
diff --git a/src/org/apache/xerces/validators/datatype/QNameDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/QNameDatatypeValidator.java
deleted file mode 100644
index 18f7575..0000000
--- a/src/org/apache/xerces/validators/datatype/QNameDatatypeValidator.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-import java.util.Hashtable;
-import java.util.Vector;
-import java.util.Enumeration;
-import java.util.Locale;
-import java.text.ParseException;
-import java.text.Collator;
-import java.util.StringTokenizer;
-import java.util.NoSuchElementException;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-import org.apache.xerces.utils.regex.RegularExpression;
-
-/**
- * QName Validator validates a QName type.
- * QName represents XML qualified names. The value 
- * space of QName is the set of tuples
- * {namespace name, local part}, where namespace 
- * name is a uriReference and local part is an NCName.
- * The lexical space of QName is the set of strings
- * that match the QName production of [Namespaces in
- * XML]. 
- * 
- * @author Jeffrey Rodriguez
- * @version $Id$
- */
-public class QNameDatatypeValidator extends  AbstractDatatypeValidator {
-    private Locale    fLocale          = null;
-    private DatatypeValidator    fBaseValidator   = null;
-    private boolean fDerivedByList             = false;
-
-    private int       fLength          = 0;
-    private int       fMaxLength       = Integer.MAX_VALUE;
-    private int       fMinLength       = 0;
-    private String    fPattern         = null;
-    private Vector    fEnumeration     = null;
-    private String    fMaxInclusive    = null;
-    private String    fMaxExclusive    = null;
-    private String    fMinInclusive    = null;
-    private String    fMinExclusive    = null;
-    private int       fFacetsDefined   = 0;
-
-    private boolean isMaxExclusiveDefined = false;
-    private boolean isMaxInclusiveDefined = false;
-    private boolean isMinExclusiveDefined = false;
-    private boolean isMinInclusiveDefined = false;
-    private RegularExpression fRegex         = null;
-
-
-    public QNameDatatypeValidator () throws InvalidDatatypeFacetException {
-        this( null, null, false ); // Native, No Facets defined, Restriction
-    }
-
-    public QNameDatatypeValidator ( DatatypeValidator base, Hashtable facets, 
-                                    boolean derivedByList ) throws InvalidDatatypeFacetException  {
-
-        setBasetype( base ); // Set base type 
-
-        fDerivedByList = derivedByList;
-
-        // Set Facets if any defined
-        if ( facets != null  ){
-            if ( fDerivedByList == false) {
-                for (Enumeration e = facets.keys(); e.hasMoreElements();) {
-                    String key = (String) e.nextElement();
-
-                    if ( key.equals(SchemaSymbols.ELT_LENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_LENGTH;
-                        String lengthValue = (String)facets.get(key);
-                        try {
-                            fLength     = Integer.parseInt( lengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"' is invalid.");
-                        }
-                        if ( fLength < 0 )
-                            throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"'  must be a nonNegativeInteger.");
-
-                    } else if (key.equals(SchemaSymbols.ELT_MINLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MINLENGTH;
-                        String minLengthValue = (String)facets.get(key);
-                        try {
-                            fMinLength     = Integer.parseInt( minLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("maxLength value '"+minLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MAXLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXLENGTH;
-                        String maxLengthValue = (String)facets.get(key);
-                        try {
-                            fMaxLength     = Integer.parseInt( maxLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("maxLength value '"+maxLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_PATTERN)) {
-                        fFacetsDefined += DatatypeValidator.FACET_PATTERN;
-                        fPattern = (String)facets.get(key);
-                        fRegex   = new RegularExpression(fPattern, "X");
-                    } else if (key.equals(SchemaSymbols.ELT_ENUMERATION)) {
-                        fFacetsDefined += DatatypeValidator.FACET_ENUMERATION;
-                        fEnumeration = (Vector)facets.get(key);
-                    } else if (key.equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXINCLUSIVE;
-                        fMaxInclusive = (String)facets.get(key);
-                    } else if (key.equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXEXCLUSIVE;
-                        fMaxExclusive = (String)facets.get(key);
-                    } else if (key.equals(SchemaSymbols.ELT_MININCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MININCLUSIVE;
-                        fMinInclusive = (String)facets.get(key);
-                    } else if (key.equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MINEXCLUSIVE;
-                        fMinExclusive = (String)facets.get(key);
-                    } else {
-                        throw new InvalidDatatypeFacetException();
-                    }
-                }
-
-                if (((fFacetsDefined & DatatypeValidator.FACET_LENGTH ) != 0 ) ) {
-                    if (((fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and maxLength to be members of facets." );  
-                    } else if (((fFacetsDefined & DatatypeValidator.FACET_MINLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and minLength to be members of facets." );
-                    }
-                }
-
-                if ( ( (fFacetsDefined & ( DatatypeValidator.FACET_MINLENGTH |
-                                           DatatypeValidator.FACET_MAXLENGTH) ) != 0 ) ) {
-                    if ( fMinLength > fMaxLength ) {
-                        throw new InvalidDatatypeFacetException( "Value of maxLength = " + fMaxLength +
-                                                                 "must be greater that the value of minLength" + fMinLength );
-                    }
-                }
-
-                isMaxExclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXEXCLUSIVE ) != 0 )?true:false;
-                isMaxInclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXINCLUSIVE ) != 0 )?true:false;
-                isMinExclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MINEXCLUSIVE ) != 0 )?true:false;
-                isMinInclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MININCLUSIVE ) != 0 )?true:false;
-
-                if ( isMaxExclusiveDefined && isMaxInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                           "It is an error for both maxInclusive and maxExclusive to be specified for the same datatype." ); 
-                }
-                if ( isMinExclusiveDefined && isMinInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                           "It is an error for both minInclusive and minExclusive to be specified for the same datatype." ); 
-                }
-            } else { //derived by list
-                for (Enumeration e = facets.keys(); e.hasMoreElements();) {
-                    String key = (String) e.nextElement();
-                    if ( key.equals(SchemaSymbols.ELT_LENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_LENGTH;
-                        String lengthValue = (String)facets.get(key);
-                        try {
-                            fLength     = Integer.parseInt( lengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"' is invalid.");
-                        }
-                        if ( fLength < 0 )
-                            throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"'  must be a nonNegativeInteger.");
-
-                    } else if (key.equals(SchemaSymbols.ELT_MINLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MINLENGTH;
-                        String minLengthValue = (String)facets.get(key);
-                        try {
-                            fMinLength     = Integer.parseInt( minLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("maxLength value '"+minLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MAXLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXLENGTH;
-                        String maxLengthValue = (String)facets.get(key);
-                        try {
-                            fMaxLength     = Integer.parseInt( maxLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("maxLength value '"+maxLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_ENUMERATION)) {
-                        fFacetsDefined += DatatypeValidator.FACET_ENUMERATION;
-                        fEnumeration    = (Vector)facets.get(key);
-                    } else {
-                        throw new InvalidDatatypeFacetException();
-                    }
-                }
-                if (((fFacetsDefined & DatatypeValidator.FACET_LENGTH ) != 0 ) ) {
-                    if (((fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and maxLength to be members of facets." );  
-                    } else if (((fFacetsDefined & DatatypeValidator.FACET_MINLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and minLength to be members of facets." );
-                    }
-                }
-
-                if ( ( (fFacetsDefined & ( DatatypeValidator.FACET_MINLENGTH |
-                                           DatatypeValidator.FACET_MAXLENGTH) ) != 0 ) ) {
-                    if ( fMinLength < fMaxLength ) {
-                        throw new InvalidDatatypeFacetException( "Value of minLength = " + fMinLength +
-                                                                 "must be greater that the value of maxLength" + fMaxLength );
-                    }
-                }
-            }
-        }// End of Facets Setting
-
-
-    }
-
-
-
-/**
-* validate that a string is a W3C string type
-* 
-* @param content A string containing the content to be validated
-* @param list
-* @exception throws InvalidDatatypeException if the content is
-*                   not a W3C string type
-* @exception InvalidDatatypeValueException
-*/
-    public Object validate(String content, Object state)  throws InvalidDatatypeValueException
-    {
-        StringTokenizer parsedList = null;
-
-        if ( fDerivedByList == true  ) { //derived by list
-            parsedList = new StringTokenizer( content );
-            try {
-                while ( parsedList.hasMoreTokens() ) {
-                    checkContentList( parsedList.nextToken() );
-                }
-            } catch ( NoSuchElementException e ) {
-                e.printStackTrace();
-            }
-        } else { //derived by list
-            checkContent( content );
-        }
-        return null;
-    }
-
-
-
-/**
-* set the locate to be used for error messages
-*/
-    public void setLocale(Locale locale) {
-        fLocale = locale;
-    }
-
-
-
-
-    private void checkContent( String content )throws InvalidDatatypeValueException
-    {
-        if ( (fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH) != 0 ) {
-            if ( content.length() > fMaxLength ) {
-                throw new InvalidDatatypeValueException("Value '"+content+
-                                                        "' with length '"+content.length()+
-                                                        "' exceeds maximum length of "+fMaxLength+".");
-            }
-        }
-        if ( (fFacetsDefined & DatatypeValidator.FACET_ENUMERATION) != 0 ) {
-            if ( fEnumeration.contains( content ) == false )
-                throw new InvalidDatatypeValueException("Value '"+content+"' must be one of "+fEnumeration);
-        }
-
-
-        if ( isMaxExclusiveDefined == true ) {
-            int comparisonResult;
-            comparisonResult  = compare( content, fMaxExclusive );
-            //System.out.println( "maxExc = " + comparisonResult );
-
-            if ( comparisonResult >= 0 ) {
-                throw new InvalidDatatypeValueException( "Value '"+content+ "'  must be " +
-                                  "lexicographically less than '" + fMaxExclusive + "'."  );
-
-            }
-
-        }
-        if ( isMaxInclusiveDefined == true ) {
-            int comparisonResult;
-            comparisonResult  = compare( content, fMaxInclusive );
-            if ( comparisonResult > 0 )
-                throw new InvalidDatatypeValueException( "Value '"+content+ "' must be " +
-                                  "lexicographically less or equal than '" + fMaxInclusive +"'." );
-        }
-
-        if ( isMinExclusiveDefined == true ) {
-            int comparisonResult;
-            comparisonResult  = compare( content, fMinExclusive );
-            //System.out.println( "minExc = " + comparisonResult );
-
-            if ( comparisonResult <= 0 )
-                throw new InvalidDatatypeValueException( "Value '"+content+ "' must be " +
-                                                         "lexicographically greater than '" + fMinExclusive + "'." );
-        }
-        if ( isMinInclusiveDefined == true ) {
-            int comparisonResult;
-            comparisonResult = compare( content, fMinInclusive );
-            //System.out.println( "minInc = " + comparisonResult );
-            if ( comparisonResult < 0 )
-                throw new InvalidDatatypeValueException( "Value '"+content+ "' must be " +
-                                                         "lexicographically greater or equal than '" + fMinInclusive  + "'." );
-        }
-
-
-        if ( (fFacetsDefined & DatatypeValidator.FACET_PATTERN ) != 0 ) {
-            if ( fRegex == null || fRegex.matches( content) == false )
-                throw new InvalidDatatypeValueException("Value '"+content+
-                                                        "' does not match regular expression facet '" + fPattern + "'." );
-        }
-    }
-
-    public Hashtable getFacets(){
-        return null;
-    }
-
-    public int compare( String content, String facetValue ){
-        Locale    loc       = Locale.getDefault();
-        Collator  collator  = Collator.getInstance( loc );
-        return collator.compare( content, facetValue );
-    }
-
-
-
-    /**
-       * Returns a copy of this object.
-       */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
-    }
-
-
-
-    private void checkContentList( String content )throws InvalidDatatypeValueException
-    {
-//Revisit
-    }
-
-
-    private void setBasetype( DatatypeValidator base) {
-        fBaseValidator = base;
-    }
-
-
-
-}
-
diff --git a/src/org/apache/xerces/validators/datatype/RecurringDurationDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/RecurringDurationDatatypeValidator.java
deleted file mode 100644
index f454ffb..0000000
--- a/src/org/apache/xerces/validators/datatype/RecurringDurationDatatypeValidator.java
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.Hashtable;
-import java.util.Vector;
-import java.util.Enumeration;
-import java.util.Locale;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.text.ParseException;
-import org.apache.xerces.utils.regex.RegularExpression;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-
-/**
- *
- *
- *
- * @author Ted Leung, George Joseph, Jeffrey Rodriguez,  
- * @version $Id$
- */
-
-public class RecurringDurationDatatypeValidator extends AbstractDatatypeValidator {
-
-    private static final boolean   fDbug        = false;
-    private Locale    fLocale           = null;
-    DatatypeValidator fBaseValidator    = null; // A Native datatype is null
-    String            fPattern          = null;
-    long              fMaxInclusive     = Long.MAX_VALUE;
-    long              fMaxExclusive     = Long.MAX_VALUE-1;
-    long              fMinInclusive     = 1L;
-    long              fMinExclusive     = 0L;
-    long              fDuration         = 0L;
-    long              fPeriod           = 0L;
-    long[]            fEnumrecurringduration = null; // Time duration is represented internally as longs
-    boolean           isMaxExclusiveDefined = false;
-    boolean           isMaxInclusiveDefined = false;
-    boolean           isMinExclusiveDefined = false;
-    boolean           isMinInclusiveDefined = false;
-    boolean           isBaseTypeTimePeriod  = false;
-    int               fFacetsDefined        = 0;
-    boolean           fDerivedByList        = false;
-    Hashtable         fFacets        = null;
-
-
-
-    private DatatypeMessageProvider fMessageProvider = new DatatypeMessageProvider();
-
-
-
-    public  RecurringDurationDatatypeValidator () throws InvalidDatatypeFacetException {
-        this( null, null, false ); // Native, No Facets defined, Restriction
-    }
-
-    public  RecurringDurationDatatypeValidator ( DatatypeValidator base, Hashtable facets, 
-                                                 boolean derivedByList ) throws InvalidDatatypeFacetException {
-
-        fDerivedByList = derivedByList;
-
-        if ( base != null )
-        {
-            setBasetype( base ); // Set base type 
-            fFacets = facets;
-        }
-
-        // Set Facets if any defined
-
-        if ( facets != null  )  {
-            if ( fDerivedByList == false ) { // Restriction
-
-                for (Enumeration e = facets.keys(); e.hasMoreElements();) {
-
-                    String key = (String) e.nextElement();
-
-                    if (key.equals(SchemaSymbols.ELT_PATTERN)) {
-                        fFacetsDefined += DatatypeValidator.FACET_PATTERN;
-                        fPattern = (String)facets.get(key);
-                    } else if (key.equals(SchemaSymbols.ELT_ENUMERATION)) {
-                        fFacetsDefined += DatatypeValidator.FACET_ENUMERATION;
-                        continue; //Treat the enumeration after this for loop
-                    } else if (key.equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXINCLUSIVE;
-                        String value = null;
-                        try {
-                            value         = ((String)facets.get(key));
-
-
-                            fMaxInclusive = normalizeRecurringDuration( value.toCharArray(), 0) ;
-                        } catch ( InvalidDatatypeValueException nfe ){
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue,
-                                                                                   DatatypeMessageProvider.MSG_NONE,
-                                                                                   new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXEXCLUSIVE;
-                        String value = null;
-                        try {
-                            value         = ((String)facets.get(key));
-                            fMaxExclusive = normalizeRecurringDuration( value.toCharArray(), 0 );
-                        } catch ( InvalidDatatypeValueException nfe ){
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue,
-                                                                                   DatatypeMessageProvider.MSG_NONE,
-                                                                                   new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MININCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MININCLUSIVE;
-                        String value = null;
-                        try {
-                            value         = ((String)facets.get(key));
-                            fMinInclusive = normalizeRecurringDuration( value.toCharArray(), 0 );
-                        } catch ( InvalidDatatypeValueException nfe ){
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue,
-                                                                                   DatatypeMessageProvider.MSG_NONE,
-                                                                                   new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MININCLUSIVE;
-                        String value = null;
-                        try {
-                            value         = ((String)facets.get(key));
-                            fMinExclusive = normalizeRecurringDuration( value.toCharArray(), 0 ); 
-                        } catch ( InvalidDatatypeValueException nfe ) {
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue,
-                                                                                   DatatypeMessageProvider.MSG_NONE,
-                                                                                   new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_PERIOD  )) {
-                        fFacetsDefined += DatatypeValidator.FACET_PERIOD;
-                        String value = null;
-                        try {
-                            value         = ((String)facets.get(key));
-                            fPeriod   = normalizeRecurringDuration( value.toCharArray(), 0 ); 
-                            if ( fDbug == true ){
-                                System.out.println( "value = " + value );
-                                System.out.println("fPeriod = " + fPeriod );
-                            }
-                        } catch ( InvalidDatatypeValueException nfe ) {
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue,
-                                                                                   DatatypeMessageProvider.MSG_NONE,
-                                                                                   new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_DURATION )) {
-                        fFacetsDefined += DatatypeValidator.FACET_DURATION;
-                        String value = null;
-                        try {
-                            value         = ((String)facets.get(key));
-                            fDuration     = normalizeRecurringDuration( value.toCharArray(), 0 ); 
-                            if ( fDbug == true ){
-                                System.out.println("fDuration = " + fDuration );
-                            }
-                        } catch ( InvalidDatatypeValueException nfe ) {
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue,
-                                                                                   DatatypeMessageProvider.MSG_NONE,
-                                                                                   new Object [] { value, key}));
-                        }
-
-
-                    } else {
-                        throw new InvalidDatatypeFacetException( getErrorString(  DatatypeMessageProvider.MSG_FORMAT_FAILURE,
-                                                                                  DatatypeMessageProvider.MSG_NONE,
-                                                                                  null));
-                    }
-                }
-
-                isMaxExclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXEXCLUSIVE ) != 0 )?true:false;
-                isMaxInclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXINCLUSIVE ) != 0 )?true:false;
-                isMinExclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MINEXCLUSIVE ) != 0 )?true:false;
-                isMinInclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MININCLUSIVE ) != 0 )?true:false;
-
-
-                if ( isMaxExclusiveDefined && isMaxInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                           "It is an error for both maxInclusive and maxExclusive to be specified for the same datatype." ); 
-                }
-                if ( isMinExclusiveDefined && isMinInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                           "It is an error for both minInclusive and minExclusive to be specified for the same datatype." ); 
-                }
-
-                if ( (fFacetsDefined & DatatypeValidator.FACET_ENUMERATION ) != 0 ) {
-                    Vector v = (Vector) facets.get(SchemaSymbols.ELT_ENUMERATION);    
-                    if (v != null) {
-                        fEnumrecurringduration = new long[v.size()];
-                        int     i     = 0;
-                        String  value = null;
-                        try {
-                            for (; i < v.size(); i++){
-                                value = (String)v.elementAt(i);
-                                fEnumrecurringduration[i] = 
-                                normalizeRecurringDuration( value.toCharArray(), 0 );
-                                boundsCheck( fEnumrecurringduration[i] ); // Check against max,min Inclusive, Exclusives
-                            }
-                            if ( fDbug == true ){
-                                System.out.println( "The enumeration vectory is " + value );
-                                for ( int enumCounter = 0;
-                                    enumCounter < this.fEnumrecurringduration.length; enumCounter++ ) {
-                                    System.out.println( "fEnumrecurringduration[" + enumCounter + "]" );
-                                }
-                            }
-                        } catch (InvalidDatatypeValueException idve) {
-                            throw new InvalidDatatypeFacetException(
-                                                                   getErrorString(DatatypeMessageProvider.InvalidEnumValue,
-                                                                                  DatatypeMessageProvider.MSG_NONE,
-                                                                                  new Object [] { v.elementAt(i)}));
-                        }
-                    }
-                }
-            
-             if( fBaseValidator != null ) { // Check if basetype of Period id null
-                        String value        = null;
-                        long   baseTypePeriod;
-                        try {
-                            Hashtable  baseValidatorFacet = fBaseValidator.getFacets();
-                            if( baseValidatorFacet != null ) {
-                                 value         = ((String)baseValidatorFacet.get(SchemaSymbols.ELT_PERIOD ));
-                                 if( value != null ) {
-                                      fPeriod       = normalizeRecurringDuration( value.toCharArray(), 0 ); 
-                                      if( fPeriod == 0 ){
-                                          isBaseTypeTimePeriod = true;
-                                      }
-                                      if ( fDbug == true ){
-                                          System.out.println( "value = " + value );
-                                          System.out.println("fPeriod = " + fPeriod );
-                                      }
-                                 }
-                            }
-                        } catch ( InvalidDatatypeValueException nfe ) {
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue,
-                                                                                   DatatypeMessageProvider.MSG_NONE,
-                                                                                   new Object [] { value, SchemaSymbols.ELT_PERIOD}));
-                        }
-             }
-
-
-
-            } else { //Derived by List TODO 
-
-            }
-        }// End Facet definition
-    }
-
-
-    /**
-     * validates a String to be a Lexical representation
-     * of a recurringduration Datatype.
-     * 
-     * @param content A string containing the content to be validated
-     * @param state
-     * @return 
-     * @exception InvalidDatatypeValueException
-     *                   If String is does not represent a
-     *                   valid recurringduration datatype.
-     */
-    public Object validate(String content, Object state) throws InvalidDatatypeValueException{
-        long normalizedValue;
-
-        if ( fDerivedByList == false  ) { //derived by constraint
-
-
-            if( fDbug == true ) {
-                 System.out.println( "Write fFacetsDefined = " + fFacetsDefined );
-                 if ( ( fFacetsDefined & DatatypeValidator.FACET_DURATION ) != 0 ){
-                     System.out.println( "Duration = " + this.fDuration );
-                 }
-                 if ( ( fFacetsDefined & DatatypeValidator.FACET_PERIOD ) != 0 ){
-                     System.out.println( "Period = " + this.fPeriod );
-                 }
-                 System.out.println("datatype = " + this.fBaseValidator );
-            }
-
-
-
-            if ( fPattern != null ) {
-                RegularExpression regex = new RegularExpression(fPattern, "X" );
-                if ( regex.matches( content) == false )
-                    throw new InvalidDatatypeValueException("Value'"+content+
-                                                            "does not match regular expression facet" + fPattern );
-            }
-
-
-
-            //normalizeRecurringDuration(content.toCharArray(), 0 );
-
-            //Calendar cal = normalizeInstant(content.toCharArray(), 0, content.length() ); 
-
-            //System.out.println( "cal = " + cal.toString() );
-            //try {
-            //boundsCheck( normalizedValue );
-            // } catch( InvalidDatatypeFacetException ex ){
-            //   throw new InvalidDatatypeValueException( "Boundary error:" );
-            //}
-
-            //if ( fEnumrecurringduration != null )
-            //  enumCheck( normalizedValue );
-
-        } else { //derived by list 
-        }
-        return null;
-    }
-
-
-    /**
-     * set the base type for this datatype
-     *
-     * @param base the validator for this type's base type
-     *
-     */
-    public void setBasetype(DatatypeValidator base) {
-        fBaseValidator = base;
-    }
-
-
-    /**
-    * set the locate to be used for error messages
-    */
-    public void setLocale(Locale locale) {
-    }
-
-
-    public int compare( String content1, String content2) {
-        return -1;
-    }
-
-    public Hashtable getFacets(){
-        return fFacets;
-    }
-
-    // Here start private methods
-    // Work in Progress ------- 
-
-    private static long normalizeRecurringDuration(char[] value, int start ) 
-        throws InvalidDatatypeValueException {
-        long   normalizedDuration = 0L;
-
-        //System.out.println("value to normalize = " + value );
-        //This method will convert the Lexical representation of re
-        //CCYY-MM-DDThh:mm:ss.sss 
-        //
-
-
-        return normalizedDuration;
-    }
-
-    public static Calendar normalizeInstant(char[] value, int start,
-                                            int length) throws InvalidDatatypeValueException
-    {
-        boolean negative=false;
-        boolean tznegative=false;
-        int     tzoffset=0;
-        int     tzhh=0,tzmm=0;
-        int     i=start,j=0,k=0,l=0,m=0;
-        final char[]ms={'0','0','0'};
-        final   Calendar cal = new GregorianCalendar();
-        final   int endindex = (start+length)-1;
-
-        try
-        {
-            if (length < 16) throw new ParseException("Value is too short.",0);
-            cal.clear();
-            cal.setLenient(false);
-//     If there's a leading sign, set the appropriate Era.
-            if (value[i]=='-'||value[i]=='+')
-            {
-                cal.set(Calendar.ERA, (value[i]=='-'?GregorianCalendar.BC:GregorianCalendar.AD));
-                i++;
-            }
-//     Grab the year (might be > 9999), month, day, hour and minute fields       
-            j=indexOf(value,i,'-',i+5);
-            if (j==-1 || j>endindex)throw new ParseException("Year separator is missing or misplaced.", i);
-            cal.set(Calendar.YEAR, parseInt(value,i,j-i));
-            i=j+1;
-            cal.set(Calendar.MONTH, parseInt(value,i,2)-1);
-            i+=2;
-            if (value[i]!='-')throw new ParseException("Month separator is missing or misplaced.",i);
-            cal.set(Calendar.DAY_OF_MONTH, parseInt(value,i+1,2));
-            i+=3;
-            if (value[i]!='T')throw new ParseException("Time separator is missing or misplaced.",i);
-            cal.set(Calendar.HOUR_OF_DAY, parseInt(value,i+1,2));
-            i+=3;
-            if (value[i]!=':')throw new ParseException("Hour separator is missing or misplaced.",i);
-            cal.set(Calendar.MINUTE, parseInt(value,i+1,2));
-            i+=3;
-//     Seconds are optional
-            if ((endindex-i)>1 && (value[i]==':'))
-            {
-                cal.set(Calendar.SECOND, parseInt(value,i+1,2));
-                i+=3;
-// Grab optional fractional seconds to 3 decimal places.
-                if (i<endindex && value[i]=='.')
-                {
-                    i++;k=0;
-                    while ((i <= endindex) && (k<3) && Character.isDigit(value[i]))
-                        ms[k++]=value[i++];
-
-                    cal.set(Calendar.MILLISECOND, parseInt(ms,0,3));
-                }
-//     Eat any remaining digits.
-                while (i<=endindex && Character.isDigit(value[i]))  i++;
-            }
-//     Check for timezone.
-            if (i<=endindex)
-            {
-                if (value[i]=='Z')
-                {
-                    cal.set(Calendar.ZONE_OFFSET, 0);
-                }
-//                      else if ((endindex-i)==2 || (endindex-i)==5)
-                else if (value[i]=='-' || value[i]=='+')
-                {
-                    tznegative = (value[i]=='-');
-                    tzhh=parseInt(value,i+1,2);
-                    if ((endindex-i)==5)
-                    {
-                        if (value[i+3] != ':')throw new ParseException("time zone must be 'hh:mm'.",i);
-                        tzmm=parseInt(value,i+4,2);
-                    }
-                    tzoffset=((tzhh*3600000)+(tzmm*60000));
-                    cal.set(Calendar.ZONE_OFFSET, (tznegative?-tzoffset:tzoffset));
-                } else throw new ParseException("Unrecognized time zone.",i);
-            }
-            return(cal);
-        } catch (Exception e)
-        {
-            if ( fDbug ){
-                e.printStackTrace();
-                return null;
-            } else  {
-                throw new InvalidDatatypeValueException("Unable to parse timeInstant "+e.toString());
-            }
-        }
-    }
-
-
-    /**
-       * Returns a copy of this object.
-       */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
-    }
-
-
-
-
-    /*
-     * check that a facet is in range, assumes that facets are compatible -- compatibility ensured by setFacets
-     */
-    private void boundsCheck(long f) throws InvalidDatatypeFacetException {
-        boolean inUpperBound = false;
-        boolean inLowerBound = false;
-
-        if ( isMaxInclusiveDefined ) {
-            inUpperBound = ( f <= fMaxInclusive );
-        } else if ( isMaxExclusiveDefined ) {
-            inUpperBound = ( f <  fMaxExclusive );
-        }
-
-        if ( isMinInclusiveDefined ) {
-            inLowerBound = ( f >= fMinInclusive );
-        } else if ( isMinExclusiveDefined ) {
-            inLowerBound = ( f >  fMinExclusive );
-        }
-
-        if ( inUpperBound == false  || inLowerBound == false ) { // within bounds ?
-            throw new InvalidDatatypeFacetException(
-                                                   getErrorString(DatatypeMessageProvider.OutOfBounds,
-                                                                  DatatypeMessageProvider.MSG_NONE,
-                                                                  new Object [] { new Long(f),"","","",""}));//Revisit
-        }
-    }
-
-    private void enumCheck(long d) throws InvalidDatatypeValueException {
-        for (int i = 0; i < this.fEnumrecurringduration.length; i++) {
-            if (d == fEnumrecurringduration[i]) return;
-        }
-        throw new InvalidDatatypeValueException(
-                                               getErrorString(DatatypeMessageProvider.NotAnEnumValue,
-                                                              DatatypeMessageProvider.MSG_NONE,
-                                                              new Object [] { new Long(d )}));
-    }
-
-    private String getErrorString(int major, int minor, Object args[]) {
-        try {
-            return fMessageProvider.createMessage(fLocale, major, minor, args);
-        } catch (Exception e) {
-            return "Illegal Errorcode "+minor;
-        }
-    }
-
-    private static final int indexOf(char[] value, int start, char s)
-    {
-        return(indexOf(value,start,s,value.length-1));
-    }
-    private static final int indexOf(char[] value, int start, char s, int max)
-    {
-        for (int i=start;i<=max;i++)if (value[i]==s) return(i);
-        return(-1);
-    }
-    private static final int indexOneOf(char[] value, int start, String s)
-    {
-        return(indexOneOf(value,start,s,value.length-1));
-    }
-    private static final int indexOneOf(char[] value, int start, String s, int max)
-    {
-        for (int i=start;i<max;i++)
-            for (int j=0;j<s.length();j++) if (value[i] == s.charAt(j))return(i);
-        return(-1);
-    }
-//     parseInt is a copy of the Integer.parseInt method, modified to accept
-// a character array.
-    private static final int parseInt(char[] s, int start, int length)     throws NumberFormatException
-    {
-        if (s == null) throw new NumberFormatException("null");
-        int radix=10;
-        int result = 0;
-        boolean negative = false;
-        int i= start;
-        int limit;
-        int multmin;
-        int digit=0;
-
-        if (length <= 0) throw new NumberFormatException(new String(s,start,length));
-        if (s[i] == '-')
-        {
-            negative = true;
-            limit = Integer.MIN_VALUE;
-            i++;
-        } else if (s[i]=='+')
-        {
-            negative = false;
-            limit = -Integer.MAX_VALUE;
-            i++;
-        } else
-        {
-            limit = -Integer.MAX_VALUE;
-        }
-        multmin = limit / radix;
-        if (i < (start+length))
-        {
-            digit = Character.digit(s[i++],radix);
-            if (digit < 0) throw new NumberFormatException(new String(s,start,length));
-            else result = -digit;
-        }
-        while (i < (start+length))
-        {
-            digit = Character.digit(s[i++],radix);
-            if (digit < 0) throw new NumberFormatException(new String(s,start,length));
-            if (result < multmin) throw new NumberFormatException(new String(s,start,length));
-            result *= radix;
-            if (result < limit + digit) throw new NumberFormatException(new String(s,start,length));
-            result -= digit;
-        }
-
-        if (negative)
-        {
-            if (i > 1) return result;
-            else throw new NumberFormatException(new String(s,start,length));
-        }
-        return -result;
-
-
-
-    }
-
-}
-
diff --git a/src/org/apache/xerces/validators/datatype/StateMessageDatatype.java b/src/org/apache/xerces/validators/datatype/StateMessageDatatype.java
deleted file mode 100644
index 85df80e..0000000
--- a/src/org/apache/xerces/validators/datatype/StateMessageDatatype.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-public interface StateMessageDatatype{
-    public Object getDatatypeObject();
-    public void   setDatatypeObject( Object data );
-    public int    getDatatypeState();
-
-}
diff --git a/src/org/apache/xerces/validators/datatype/StringDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/StringDatatypeValidator.java
deleted file mode 100644
index c68fb1d..0000000
--- a/src/org/apache/xerces/validators/datatype/StringDatatypeValidator.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.Hashtable;
-import java.util.Vector;
-import java.util.Enumeration;
-import java.util.Locale;
-import java.text.Collator;
-import java.util.Enumeration;
-import java.util.StringTokenizer;
-import java.util.NoSuchElementException;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-import org.apache.xerces.utils.regex.RegularExpression;
-
-/**
- * StringValidator validates that XML content is a W3C string type.
- * @author Ted Leung
- * @author Kito D. Mann, Virtua Communications Corp.
- * @author Jeffrey Rodriguez
- * @version $Id$
- */
-public class StringDatatypeValidator extends AbstractDatatypeValidator{
-    private Locale     fLocale          = null;
-    DatatypeValidator  fBaseValidator   = null; // Native datatypes have null
-
-    private int        fLength           = 0;
-    private int        fMaxLength        = Integer.MAX_VALUE;
-    private int        fMinLength        = 0;
-    private String     fPattern          = null;
-    private Vector     fEnumeration      = null;
-    private String     fMaxInclusive     = null;
-    private String     fMaxExclusive     = null;
-    private String     fMinInclusive     = null;
-    private String     fMinExclusive     = null;
-    private int        fFacetsDefined    = 0;
-    private boolean    fDerivedByList    = false;//default
-
-    private boolean    isMaxExclusiveDefined = false;
-    private boolean    isMaxInclusiveDefined = false;
-    private boolean    isMinExclusiveDefined = false;
-    private boolean    isMinInclusiveDefined = false;
-    private RegularExpression fRegex         = null;
-
-
-
-
-    public  StringDatatypeValidator () throws InvalidDatatypeFacetException{
-        this( null, null, false ); // Native, No Facets defined, Restriction
-
-    }
-
-    public StringDatatypeValidator ( DatatypeValidator base, Hashtable facets, 
-                                     boolean derivedByList ) throws InvalidDatatypeFacetException {
-
-        setBasetype( base ); // Set base type 
-
-        fDerivedByList = derivedByList;
-
-        // Set Facets if any defined
-        //fFacetsDefined = 0;
-        if ( facets != null  ){
-            if ( fDerivedByList == false) {
-
-                for (Enumeration e = facets.keys(); e.hasMoreElements();) {
-                    String key = (String) e.nextElement();
-
-                    if ( key.equals(SchemaSymbols.ELT_LENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_LENGTH;
-                        String lengthValue = (String)facets.get(key);
-                        try {
-                            fLength     = Integer.parseInt( lengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"' is invalid.");
-                        }
-                        if ( fLength < 0 )
-                            throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"'  must be a nonNegativeInteger.");
-
-                    } else if (key.equals(SchemaSymbols.ELT_MINLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MINLENGTH;
-                        String minLengthValue = (String)facets.get(key);
-                        try {
-                            fMinLength     = Integer.parseInt( minLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("minLength value '"+minLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MAXLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXLENGTH;
-                        String maxLengthValue = (String)facets.get(key);
-                        try {
-                            fMaxLength     = Integer.parseInt( maxLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("maxLength value '"+maxLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_PATTERN)) {
-                        fFacetsDefined += DatatypeValidator.FACET_PATTERN;
-                        fPattern = (String)facets.get(key);
-                        fRegex   = new RegularExpression(fPattern, "X");
-                    } else if (key.equals(SchemaSymbols.ELT_ENUMERATION)) {
-                        fFacetsDefined += DatatypeValidator.FACET_ENUMERATION;
-                        fEnumeration = (Vector)facets.get(key);
-                    } else if (key.equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXINCLUSIVE;
-                        fMaxInclusive = (String)facets.get(key);
-                    } else if (key.equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXEXCLUSIVE;
-                        fMaxExclusive = (String)facets.get(key);
-                    } else if (key.equals(SchemaSymbols.ELT_MININCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MININCLUSIVE;
-                        fMinInclusive = (String)facets.get(key);
-                    } else if (key.equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MINEXCLUSIVE;
-                        fMinExclusive = (String)facets.get(key);
-                    } else {
-                        throw new InvalidDatatypeFacetException("invalid facet tag : " + key);
-                    }
-                }
-
-                if (((fFacetsDefined & DatatypeValidator.FACET_LENGTH ) != 0 ) ) {
-                    if (((fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and maxLength to be members of facets." );  
-                    } else if (((fFacetsDefined & DatatypeValidator.FACET_MINLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and minLength to be members of facets." );
-                    }
-                }
-
-                if ( ( (fFacetsDefined & ( DatatypeValidator.FACET_MINLENGTH |
-                                           DatatypeValidator.FACET_MAXLENGTH) ) != 0 ) ) {
-                    if ( fMinLength > fMaxLength ) {
-                        throw new InvalidDatatypeFacetException( "Value of minLength = '" + fMinLength +
-                                                                 "'must be less than the value of maxLength = '" + fMaxLength + "'.");
-                    }
-                }
-
-                isMaxExclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXEXCLUSIVE ) != 0 )?true:false;
-                isMaxInclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXINCLUSIVE ) != 0 )?true:false;
-                isMinExclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MINEXCLUSIVE ) != 0 )?true:false;
-                isMinInclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MININCLUSIVE ) != 0 )?true:false;
-
-                if ( isMaxExclusiveDefined && isMaxInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                           "It is an error for both maxInclusive and maxExclusive to be specified for the same datatype." ); 
-                }
-                if ( isMinExclusiveDefined && isMinInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                           "It is an error for both minInclusive and minExclusive to be specified for the same datatype." ); 
-                }
-            } else { //derived by list
-                for (Enumeration e = facets.keys(); e.hasMoreElements();) {
-                    String key = (String) e.nextElement();
-                    if ( key.equals(SchemaSymbols.ELT_LENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_LENGTH;
-                        String lengthValue = (String)facets.get(key);
-                        try {
-                            fLength     = Integer.parseInt( lengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"' is invalid.");
-                        }
-                        if ( fLength < 0 )
-                            throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"'  must be a nonNegativeInteger.");
-
-                    } else if (key.equals(SchemaSymbols.ELT_MINLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MINLENGTH;
-                        String minLengthValue = (String)facets.get(key);
-                        try {
-                            fMinLength     = Integer.parseInt( minLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("maxLength value '"+minLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MAXLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXLENGTH;
-                        String maxLengthValue = (String)facets.get(key);
-                        try {
-                            fMaxLength     = Integer.parseInt( maxLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("maxLength value '"+maxLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_ENUMERATION)) {
-                        fFacetsDefined += DatatypeValidator.FACET_ENUMERATION;
-                        fEnumeration    = (Vector)facets.get(key);
-                    } else {
-                        throw new InvalidDatatypeFacetException("invalid facet tag : " + key);
-                    }
-                }
-                if (((fFacetsDefined & DatatypeValidator.FACET_LENGTH ) != 0 ) ) {
-                    if (((fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and maxLength to be members of facets." );  
-                    } else if (((fFacetsDefined & DatatypeValidator.FACET_MINLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and minLength to be members of facets." );
-                    }
-                }
-
-                if ( ( (fFacetsDefined & ( DatatypeValidator.FACET_MINLENGTH |
-                                           DatatypeValidator.FACET_MAXLENGTH) ) != 0 ) ) {
-                    if ( fMinLength > fMaxLength ) {
-                        throw new InvalidDatatypeFacetException( "Value of minLength = " + fMinLength +
-                                                                 "must be greater that the value of maxLength" + fMaxLength );
-                    }
-                }
-            }
-        }// End of Facets Setting
-    }
-
-
-
-
-    /**
-     * validate that a string is a W3C string type
-     * 
-     * @param content A string containing the content to be validated
-     * @param list
-     * @exception throws InvalidDatatypeException if the content is
-     *                   not a W3C string type
-     * @exception InvalidDatatypeValueException
-     */
-    public Object validate(String content, Object state)  throws InvalidDatatypeValueException
-    {
-        if ( fDerivedByList == false  ) {
-            if (fFacetsDefined != 0 )//Any facets to validate
-                checkContent( content, state );
-        } else { //derived by list 
-            checkContentList( content, state );
-        }
-        return null;
-    }
-
-
-    /**
-     * set the locate to be used for error messages
-     */
-    public void setLocale(Locale locale) {
-        fLocale = locale;
-    }
-
-
-    /**
-     * 
-     * @return                          A Hashtable containing the facets
-     *         for this datatype.
-     */
-    public Hashtable getFacets(){
-        return null;
-    }
-
-    private void checkContent( String content, Object state )throws InvalidDatatypeValueException
-    {
-
-        if ( this.fBaseValidator != null ) {//validate against parent type if any
-            this.fBaseValidator.validate( content, state );
-        }
-
-        if ( (fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH) != 0 ) {
-            if ( content.length() > fMaxLength ) {
-                throw new InvalidDatatypeValueException("Value '"+content+
-                                                        "' with length '"+content.length()+
-                                                        "' exceeds maximum length facet of '"+fMaxLength+"'.");
-            }
-        }
-        if ( (fFacetsDefined & DatatypeValidator.FACET_MINLENGTH) != 0 ) {
-            if ( content.length() < fMinLength ) {
-                throw new InvalidDatatypeValueException("Value '"+content+
-                                                        "' with length '"+content.length()+
-                                                        "' is less than minimum length facet of '"+fMinLength+"'." );
-            }
-        }
-
-        if ( (fFacetsDefined & DatatypeValidator.FACET_LENGTH) != 0 ) {
-            if ( content.length() != fLength ) {
-                throw new InvalidDatatypeValueException("Value '"+content+
-                                                        "' with length '"+content.length()+
-                                                        "' is not equal to length facet '"+fLength+"'.");
-            }
-        }
-
-
-
-        if ( (fFacetsDefined & DatatypeValidator.FACET_ENUMERATION) != 0 ) {
-            if ( fEnumeration.contains( content ) == false )
-                throw new InvalidDatatypeValueException("Value '"+content+"' must be one of "+fEnumeration);
-        }
-
-        if ( isMaxExclusiveDefined == true ) {
-            int comparisonResult;
-            comparisonResult  = compare( content, fMaxExclusive );
-            if ( comparisonResult >= 0 ) {
-                throw new InvalidDatatypeValueException( "MaxExclusive:Value '"+content+ "'  must be " +
-                                                         "lexicographically less than" + fMaxExclusive );
-
-            }
-
-        }
-        if ( isMaxInclusiveDefined == true ) {
-            int comparisonResult;
-            comparisonResult  = compare( content, fMaxInclusive );
-            if ( comparisonResult > 0 )
-                throw new InvalidDatatypeValueException( "MaxInclusive:Value '"+content+ "' must be " +
-                                                         "lexicographically less or equal than" + fMaxInclusive );
-        }
-
-        if ( isMinExclusiveDefined == true ) {
-            int comparisonResult;
-            comparisonResult  = compare( content, fMinExclusive );
-
-            //System.out.println( "exclusive = " + comparisonResult );
-
-            if ( comparisonResult <= 0 )
-                throw new InvalidDatatypeValueException( "MinExclusive:Value '"+content+ "' must be " +
-                                                         "lexicographically greater than" + fMinExclusive );
-        }
-        if ( isMinInclusiveDefined == true ) {
-            int comparisonResult;
-            comparisonResult = compare( content, fMinInclusive );
-            //System.out.println( "inclusive = " + comparisonResult );
-            if ( comparisonResult < 0 )
-                throw new InvalidDatatypeValueException( "MinInclusive:Value '"+content+ "' must be " +
-                                                         "lexicographically greater or equal than '" + fMinInclusive  + "'." );
-        }
-
-
-        if ( (fFacetsDefined & DatatypeValidator.FACET_PATTERN ) != 0 ) {
-            //RegularExpression regex = new RegularExpression(fPattern );
-            if ( fRegex == null || fRegex.matches( content) == false )
-                throw new InvalidDatatypeValueException("Value '"+content+
-                                                        "' does not match regular expression facet '" + fPattern + "'." );
-        }
-
-    }
-    public int compare( String content, String facetValue ){
-        Locale    loc       = Locale.getDefault();
-        Collator  collator  = Collator.getInstance( loc );
-        return collator.compare( content, facetValue );
-    }
-
-    /**
-   * Returns a copy of this object.
-   */
-    public Object clone() throws CloneNotSupportedException  {
-        StringDatatypeValidator newObj = null;
-        try {
-            newObj = new StringDatatypeValidator();
-
-            newObj.fLocale           =  this.fLocale;
-            newObj.fBaseValidator    =  this.fBaseValidator;
-            newObj.fLength           =  this.fLength;
-            newObj.fMaxLength        =  this.fMaxLength;
-            newObj.fMinLength        =  this.fMinLength;
-            newObj.fPattern          =  this.fPattern;
-            newObj.fEnumeration      =  this.fEnumeration;
-            newObj.fMaxInclusive     =  this.fMaxInclusive;
-            newObj.fMaxExclusive     =  this.fMaxExclusive;
-            newObj.fMinInclusive     =  this.fMinInclusive;
-            newObj.fMinExclusive     =  this.fMinExclusive;
-            newObj.fFacetsDefined    =  this.fFacetsDefined;
-            newObj.fDerivedByList    =  this.fDerivedByList;
-            newObj.isMaxExclusiveDefined = this.isMaxExclusiveDefined;
-            newObj.isMaxInclusiveDefined = this.isMaxInclusiveDefined;
-            newObj.isMinExclusiveDefined = this.isMinExclusiveDefined;
-            newObj.isMinInclusiveDefined = this.isMinInclusiveDefined;
-        } catch ( InvalidDatatypeFacetException ex) {
-            ex.printStackTrace();
-        }
-        return newObj;
-    }
-
-    // Private methods
-    private void checkContentList( String content,  Object state )throws InvalidDatatypeValueException
-    {
-        StringTokenizer parsedList = new StringTokenizer( content );
-        try {
-            int numberOfTokens =  parsedList.countTokens();
-            if ( (fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH) != 0 ) {
-                if ( numberOfTokens > fMaxLength ) {
-                    throw new InvalidDatatypeValueException("Value '"+content+
-                                                            "' with length ='"+  numberOfTokens + "'tokens"+
-                                                            "' exceeds maximum length facet with  '"+fMaxLength+"' tokens.");
-                }
-            }
-            if ( (fFacetsDefined & DatatypeValidator.FACET_MINLENGTH) != 0 ) {
-                if ( numberOfTokens < fMinLength ) {
-                    throw new InvalidDatatypeValueException("Value '"+content+
-                                                            "' with length ='"+ numberOfTokens+ "'tokens" +
-                                                            "' is less than minimum length facet with '"+fMinLength+"' tokens." );
-                }
-            }
-
-            if ( (fFacetsDefined & DatatypeValidator.FACET_LENGTH) != 0 ) {
-                if ( numberOfTokens != fLength ) {
-                    throw new InvalidDatatypeValueException("Value '"+content+
-                                                            "' with length ='"+ numberOfTokens+ "'tokens" +
-                                                            "' is not equal to length facet with '"+fLength+"'. tokens");
-                }
-            }
-
-            if ( (fFacetsDefined & DatatypeValidator.FACET_ENUMERATION) != 0 ) {
-                if ( fEnumeration.contains( content ) == false )
-                    throw new InvalidDatatypeValueException("Value '"+
-                                                            content+"' must be one of "+fEnumeration);
-            }
-            while ( parsedList.hasMoreTokens() ) {       //Check actual list content
-                if ( this.fBaseValidator != null ) {//validate against parent type if any
-                    this.fBaseValidator.validate( parsedList.nextToken(), state );
-                }
-            }
-        } catch ( NoSuchElementException e ) {
-            e.printStackTrace();
-        }
-    }
-
-    private void setBasetype( DatatypeValidator base) {
-        fBaseValidator = base;
-    }
-
-}
-
diff --git a/src/org/apache/xerces/validators/datatype/TimeDurationDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/TimeDurationDatatypeValidator.java
deleted file mode 100644
index 1773985..0000000
--- a/src/org/apache/xerces/validators/datatype/TimeDurationDatatypeValidator.java
+++ /dev/null
@@ -1,741 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.Hashtable;
-import java.util.Vector;
-import java.util.Enumeration;
-import java.util.Locale;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.text.ParseException;
-import org.apache.xerces.utils.regex.RegularExpression;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-
-/**
- *
- * TimeDurationValidator validates that XML content is a W3C timeDuration.
- *
- * @author Ted Leung, George Joseph
- * @version $Id$
- */
-
-public class TimeDurationDatatypeValidator extends AbstractDatatypeValidator {
-
-   private Locale            fLocale           = null;
-   private DatatypeValidator fBaseValidator    = null; // A Native datatype is null
-   private String            fPattern          = null;
-   private long              fMaxInclusive     = 0L;
-   private long              fMaxExclusive     = 0L;
-   private long              fMinInclusive     = 0L;
-   private long              fMinExclusive     = 0L;
-   private long              fDuration         = 0L;
-   private long              fPeriod           = 0L;
-
-
-   private boolean           isMaxExclusiveDefined = false;
-   private boolean           isMaxInclusiveDefined = false;
-   private boolean           isMinExclusiveDefined = false;
-   private boolean           isMinInclusiveDefined = false;
-
-   private int               fFacetsDefined        = 0;
-
-   private boolean           fDerivedByList        = false;
-
-
-   private long[]            fEnumTimeDuration = null; // Time duration is represented internally as longs
-
-   private DatatypeMessageProvider fMessageProvider = new DatatypeMessageProvider();
-
-
-    public  TimeDurationDatatypeValidator () throws InvalidDatatypeFacetException {
-        this( null, null, false ); // Native, No Facets defined, Restriction
-    }
-
-    public  TimeDurationDatatypeValidator ( DatatypeValidator base, Hashtable facets, 
-                  boolean derivedByList ) throws InvalidDatatypeFacetException {
-        if ( base != null )
-            setBasetype( base ); // Set base type 
-
-
-        fDerivedByList = derivedByList;
-        // Set Facets if any defined
-
-        if ( facets != null  )  {
-            if ( fDerivedByList == false ) { // Restriction
-                if (fBaseValidator != null)
-                    //if (!fBaseValidator.ensureFacetsAreConsistent(facets))
-                      //  throw new InvalidDatatypeFacetException(
-                        //                                       getErrorString( DatatypeMessageProvider.FacetsInconsistent,
-                          //                                                     DatatypeMessageProvider.MSG_NONE, null));
-
-                for (Enumeration e = facets.keys(); e.hasMoreElements();) {
-
-                    String key = (String) e.nextElement();
-
-                    if (key.equals(SchemaSymbols.ELT_PATTERN)) {
-                        fFacetsDefined += DatatypeValidator.FACET_PATTERN;
-                        fPattern = (String)facets.get(key);
-                    } else if (key.equals(SchemaSymbols.ELT_ENUMERATION)) {
-                        fFacetsDefined += DatatypeValidator.FACET_ENUMERATION;
-                        continue; //Treat the enumeration after this for loop
-                    } else if (key.equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXINCLUSIVE;
-                        String value = null;
-                        try {
-                            value         = ((String)facets.get(key));
-                            fMaxInclusive = normalizeDuration( value.toCharArray(), 0 ); 
-                        } catch ( InvalidDatatypeValueException nfe ){
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue,
-                                                                                   DatatypeMessageProvider.MSG_NONE,
-                                                                                   new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXEXCLUSIVE;
-                        String value = null;
-                        try {
-                            value         = ((String)facets.get(key));
-                            fMaxExclusive = normalizeDuration( value.toCharArray(), 0 );
-                        } catch ( InvalidDatatypeValueException nfe ){
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue,
-                                                                                   DatatypeMessageProvider.MSG_NONE,
-                                                                                   new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MININCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MININCLUSIVE;
-                        String value = null;
-                        try {
-                            value         = ((String)facets.get(key));
-                            fMinInclusive = normalizeDuration( value.toCharArray(), 0 );
-                        } catch ( InvalidDatatypeValueException nfe ){
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue,
-                                                                                   DatatypeMessageProvider.MSG_NONE,
-                                                                                   new Object [] { value, key}));
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
-                        fFacetsDefined += DatatypeValidator.FACET_MININCLUSIVE;
-                        String value = null;
-                        try {
-                            value         = ((String)facets.get(key));
-                            fMinExclusive = normalizeDuration( value.toCharArray(), 0 ); 
-
-                        } catch ( InvalidDatatypeValueException nfe ) {
-                            throw new InvalidDatatypeFacetException( getErrorString(
-                                                                                   DatatypeMessageProvider.IllegalFacetValue,
-                                                                                   DatatypeMessageProvider.MSG_NONE,
-                                                                                   new Object [] { value, key}));
-                        }
-                    } else {
-                        throw new InvalidDatatypeFacetException( getErrorString(  DatatypeMessageProvider.MSG_FORMAT_FAILURE,
-                                                                                  DatatypeMessageProvider.MSG_NONE,
-                                                                                  null));
-                    }
-                }
-
-                isMaxExclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXEXCLUSIVE ) != 0 )?true:false;
-                isMaxInclusiveDefined = ((fFacetsDefined & 
-                                          DatatypeValidator.FACET_MAXINCLUSIVE ) != 0 )?true:false;
-                isMinExclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MINEXCLUSIVE ) != 0 )?true:false;
-                isMinInclusiveDefined = ((fFacetsDefined &
-                                          DatatypeValidator.FACET_MININCLUSIVE ) != 0 )?true:false;
-
-
-                if ( isMaxExclusiveDefined && isMaxInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                "It is an error for both maxInclusive and maxExclusive to be specified for the same datatype." ); 
-                }
-                if ( isMinExclusiveDefined && isMinInclusiveDefined ) {
-                    throw new InvalidDatatypeFacetException(
-                                                "It is an error for both minInclusive and minExclusive to be specified for the same datatype." ); 
-                }
-
-
-                if ( (fFacetsDefined & DatatypeValidator.FACET_ENUMERATION ) != 0 ) {
-                    Vector v = (Vector) facets.get(SchemaSymbols.ELT_ENUMERATION);    
-                    if (v != null) {
-                        fEnumTimeDuration = new long[v.size()];
-                        int     i     = 0;
-                        String  value = null;
-                        try {
-                            for (; i < v.size(); i++){
-                                value = (String)v.elementAt(i);
-                                fEnumTimeDuration[i] = 
-                                normalizeDuration( value.toCharArray(),0 );
-                                boundsCheck(fEnumTimeDuration[i]); // Check against max,min Inclusive, Exclusives
-                            }
-                        } catch (InvalidDatatypeValueException idve) {
-                            throw new InvalidDatatypeFacetException(
-                                                                   getErrorString(DatatypeMessageProvider.InvalidEnumValue,
-                                                                                  DatatypeMessageProvider.MSG_NONE,
-                                                                                  new Object [] { v.elementAt(i)}));
-                        }
-                    }
-                }
-            } else { //Derived by List TODO 
-
-            }
-        }// End Facet definition
-    }
-
-
-    /**
-     * validates a String to be a Lexical representation
-     * of a TimeDuration Datatype.
-     * 
-     * @param content A string containing the content to be validated
-     * @param state
-     * @return 
-     * @exception InvalidDatatypeValueException
-     *                   If String is does not represent a
-     *                   valid TimeDuration datatype.
-     */
-    public Object validate(String content, Object state) 
-                                       throws InvalidDatatypeValueException{
-        long normalizedValue;
-
-        if ( fDerivedByList == false  ) { //derived by constraint
-             if ( fPattern != null ) {
-                 RegularExpression regex = new RegularExpression(fPattern, "X" );
-                 if ( regex.matches( content) == false )
-                     throw new InvalidDatatypeValueException("Value'"+content+
-                                  "does not match regular expression facet" + fPattern );
-             }
-
-             normalizedValue = normalizeDuration(content.toCharArray(), 0 ); 
-             try {
-                 boundsCheck( normalizedValue );
-             } catch( InvalidDatatypeFacetException ex ){
-                 throw new InvalidDatatypeValueException( "Boundary Exception" );
-             }
-
-             if( fEnumTimeDuration != null )
-                 enumCheck( normalizedValue );
-
-        } else { //derived by list 
-        }
-        return null;
-    }
-
-
-    /**
-     * set the base type for this datatype
-     *
-     * @param base the validator for this type's base type
-     *
-     */
-    public void setBasetype(DatatypeValidator base) {
-        fBaseValidator = base;
-    }
-
-
-    /**
-    * set the locate to be used for error messages
-    */
-    public void setLocale(Locale locale) {
-    }
-
-
-    public int compare( String content1, String content2) {
-        return -1;
-    }
-
-    public Hashtable getFacets(){
-        return null;
-    }
-
-    public static long normalizeDuration(char[] value, int start ) 
-    throws InvalidDatatypeValueException
-    {
-        int i=0, j=0, k=0, l=0, m=0;
-        int sepindex  = 0;
-        int index     = start;
-        int lindex    = 0;
-        int endindex  = (start+ value.length)-1;
-        int pendindex = endindex;
-
-        final char[] dseps = {'Y','M','D'};
-        final char[] tseps = {'H','M','S'};
-        final char[] msc = {'0','0','0'};
-
-        final int[] buckets = new int[Calendar.FIELD_COUNT];
-        for (i=0;i<buckets.length;i++)
-            buckets[i]=0;
-
-        boolean intime           = false;
-        boolean fixed            = false;
-        boolean p1negative       = false;
-        boolean p2negative       = false;
-        boolean p1specified      = false;
-        boolean p2specified      = false;
-        GregorianCalendar cstart = null;
-        GregorianCalendar cend   = null;
-
-        //Start phase 1: capture start and/or end instant.
-        try
-        {
-            if (value[index]=='-')
-            {
-                p1negative=true;
-            }
-            //Look for the forward slash.
-            int ix = indexOf(value, start, '/');
-
-            if (ix > -1 && ix < endindex)
-            {
-                if (value[ix+1]=='-')
-                {
-                    p2negative=true;
-                }
-                //If the first term starts with a 'P', pin it for later parsing 
-                if (value[(p1negative?index+1:index)]=='P')
-                {
-                    if (p1negative)
-                        index++;
-                    p1specified = true;
-                    pendindex   = ix-1;
-                }
-                //Otherwise parse it for a timeInstant
-                else
-                {
-                    cstart = (GregorianCalendar) normalizeInstant(value, index, ix-index);
-                }
-                //If the second term starts with a 'P', pin it for later parsing 
-                if (value[(p2negative?(ix+2):(ix+1))]=='P')
-                {
-                    p2specified=true;
-                    index=(p2negative?(ix+2):(ix+1));
-                }
-                //Otherwise parse it for a timeInstant
-                else
-                {
-                    ix++;
-                    cend = (GregorianCalendar)  normalizeInstant(value,ix,(endindex-ix)+1);
-                }
-            }
-            //Only one term specified.
-            else
-            {
-                index=(p1negative?(start+1):(start));
-            }
-            //If both terms are instants, return the millisecond difference
-            if (cstart != null && cend != null)
-            {
-                return((cend.getTime().getTime() - cstart.getTime().getTime()));
-            }
-            //If both terms are 'P', error.
-            if (p1specified && p2specified)
-                throw new ParseException("Period cannot be expressed as 2 durations.", 0);
-
-            if (p1specified && value[index] != 'P')
-            {
-                throw new ParseException("Invalid start character for timeDuration:"+value[index], index);
-            }
-            if (p2specified && value[index] != 'P')
-            {
-                throw new ParseException("Invalid start character for timeDuration:"+value[index], index);
-            }
-        } catch (Exception e)
-        {
-            throw new InvalidDatatypeValueException(e.toString());
-        }
-        //Second phase....parse 'P' term
-        try
-        {
-
-            lindex=index+1;
-            for (i=index+1;i<=pendindex;i++)
-            {
-                //Accumulate digits.
-                if (Character.isDigit(value[i]) || value[i]=='.')
-                {
-                    if (value[i]=='.')fixed=true;
-                    continue;
-                }
-                if (value[i]=='T')
-                {
-                    intime=true;
-                    sepindex=0;
-                    lindex=i+1;
-                    continue;
-                }
-                //If you get a separator, it must be appropriate for the section.
-                sepindex = indexOf((intime?tseps:dseps), sepindex, value[i]);
-                if (sepindex == -1)
-                    throw new ParseException("Illegal or misplaced separator.", i);
-                sepindex++;
-                //Fractional digits are allowed only for seconds.
-                if (fixed && value[i]!='S')
-                    throw new ParseException("Fractional digits allowed only for 'seconds'.", i);
-
-                j=0;
-                switch (value[i])
-                {
-                case('Y'):
-                    {
-                        if (intime)throw new ParseException("Year must be specified before 'T' separator.", i);
-                        buckets[Calendar.YEAR]= parseInt(value, lindex, i-lindex);
-                        break;
-                    }
-                case('D'):
-                    {
-                        if (intime)throw new ParseException("Days must be specified before 'T' separator.", i);
-                        buckets[Calendar.DAY_OF_MONTH]= parseInt(value, lindex, i-lindex);
-                        break;
-                    }
-                case('H'):
-                    {
-                        if (!intime)throw new ParseException("Hours must be specified after 'T' separator.", i);
-                        buckets[Calendar.HOUR_OF_DAY]= parseInt(value, lindex, i-lindex);
-                        break;
-                    }
-                case('M'):
-                    {
-                        buckets[(intime?Calendar.MINUTE:Calendar.MONTH)]= parseInt(value, lindex, i-lindex);
-                        break;
-                    }
-                case('S'):
-                    {
-                        if (!intime)throw new ParseException("Seconds must be specified after 'T' separator.", i);
-                        if (!fixed)buckets[Calendar.SECOND]= parseInt(value, lindex, i-lindex);
-                        else
-                        {
-                            int ps = indexOf(value, lindex, '.');
-                            buckets[Calendar.SECOND]= parseInt(value, lindex, ps-lindex);
-                            ps++;k=0;
-                            while ((ps <= pendindex) && (k<3) && Character.isDigit(value[ps]))
-                                msc[k++]=value[ps++];
-                            buckets[Calendar.MILLISECOND]= parseInt(msc, 0, 3);
-                            fixed=false;
-                        }
-                        break;
-                    }
-                default:
-                    {
-                        throw new ParseException("Illegal 'picture' character: "+value[i], i);
-                    }
-                }
-                lindex=i+1;
-            }
-        } catch (Exception e)
-        {
-            throw new InvalidDatatypeValueException(e.toString());
-        }
-        //Third phase, make the calculations.
-        try
-        {
-            //Roll the start calendar forward and return difference.
-            if (cstart !=null)
-            {
-                long st = cstart.getTime().getTime();
-                for (k=0;k<buckets.length;k++)
-                    if (buckets[k]!=0)cstart.add(k, (p2negative?-buckets[k]:buckets[k]));
-                long ms = cstart.getTime().getTime();
-                return((ms-st));
-            }
-            //Roll the end calendar backward and return difference.
-            if (cend !=null)
-            {
-                long st = cend.getTime().getTime();
-                for (k=0;k<buckets.length;k++)
-                    if (buckets[k]>0) cend.add(k, (p1negative?buckets[k]:-buckets[k]));
-                long ms = cend.getTime().getTime();
-                return((ms-st));
-            }
-            //Otherwise roll the relative specification forward and reverse the sing as appropriate.	
-            long r=(((long)(( (buckets[Calendar.YEAR]*31104000L)+
-                              (buckets[Calendar.MONTH]*2592000L)+
-                              (buckets[Calendar.DAY_OF_MONTH]*86400L)+
-                              (buckets[Calendar.HOUR_OF_DAY]*3600L)+
-                              (buckets[Calendar.MINUTE]*60L)+
-                              (buckets[Calendar.SECOND]))*1000L)+
-                     (buckets[Calendar.MILLISECOND])));
-
-            return((p1negative?-r:r));
-        } catch (Exception e)
-        {
-            throw new InvalidDatatypeValueException(e.toString());
-        }
-    }
-
-    public static Calendar normalizeInstant(char[] value, int start,
-                                 int length) throws InvalidDatatypeValueException
-    {
-        boolean negative=false;
-        boolean tznegative=false;
-        int     tzoffset=0;
-        int     tzhh=0,tzmm=0;
-        int     i=start,j=0,k=0,l=0,m=0;
-        final char[]ms={'0','0','0'};
-        final   Calendar cal = new GregorianCalendar();
-        final   int endindex = (start+length)-1;
-
-        try
-        {
-            if (length < 16) throw new ParseException("Value is too short.",0);
-            cal.clear();
-            cal.setLenient(false);
-//	If there's a leading sign, set the appropriate Era.
-            if (value[i]=='-'||value[i]=='+')
-            {
-                cal.set(Calendar.ERA, (value[i]=='-'?GregorianCalendar.BC:GregorianCalendar.AD));
-                i++;
-            }
-//	Grab the year (might be > 9999), month, day, hour and minute fields  	
-            j=indexOf(value,i,'-',i+5);
-            if (j==-1 || j>endindex)throw new ParseException("Year separator is missing or misplaced.", i);
-            cal.set(Calendar.YEAR, parseInt(value,i,j-i));
-            i=j+1;
-            cal.set(Calendar.MONTH, parseInt(value,i,2)-1);
-            i+=2;
-            if (value[i]!='-')throw new ParseException("Month separator is missing or misplaced.",i);
-            cal.set(Calendar.DAY_OF_MONTH, parseInt(value,i+1,2));
-            i+=3;
-            if (value[i]!='T')throw new ParseException("Time separator is missing or misplaced.",i);
-            cal.set(Calendar.HOUR_OF_DAY, parseInt(value,i+1,2));
-            i+=3;
-            if (value[i]!=':')throw new ParseException("Hour separator is missing or misplaced.",i);
-            cal.set(Calendar.MINUTE, parseInt(value,i+1,2));
-            i+=3;
-//	Seconds are optional
-            if ((endindex-i)>1 && (value[i]==':'))
-            {
-                cal.set(Calendar.SECOND, parseInt(value,i+1,2));
-                i+=3;
-// Grab optional fractional seconds to 3 decimal places.
-                if (i<endindex && value[i]=='.')
-                {
-                    i++;k=0;
-                    while ((i <= endindex) && (k<3) && Character.isDigit(value[i]))
-                        ms[k++]=value[i++];
-
-                    cal.set(Calendar.MILLISECOND, parseInt(ms,0,3));
-                }
-//	Eat any remaining digits.
-                while (i<=endindex && Character.isDigit(value[i]))  i++;
-            }
-//	Check for timezone.
-            if (i<=endindex)
-            {
-                if (value[i]=='Z')
-                {
-                    cal.set(Calendar.ZONE_OFFSET, 0);
-                }
-//  				else if ((endindex-i)==2 || (endindex-i)==5)
-                else if (value[i]=='-' || value[i]=='+')
-                {
-                    tznegative = (value[i]=='-');
-                    tzhh=parseInt(value,i+1,2);
-                    if ((endindex-i)==5)
-                    {
-                        if (value[i+3] != ':')throw new ParseException("time zone must be 'hh:mm'.",i);
-                        tzmm=parseInt(value,i+4,2);
-                    }
-                    tzoffset=((tzhh*3600000)+(tzmm*60000));
-                    cal.set(Calendar.ZONE_OFFSET, (tznegative?-tzoffset:tzoffset));
-                } else throw new ParseException("Unrecognized time zone.",i);
-            }
-            return(cal);
-        } catch (Exception e)
-        {
-            e.printStackTrace();
-            throw new InvalidDatatypeValueException("Unable to parse timeInstant "+e.toString());
-        }
-    }
-
-  /**
-     * Returns a copy of this object.
-     */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
-    }
-
-
-
-
-
-    /*
-     * check that a facet is in range, assumes that facets are compatible -- compatibility ensured by setFacets
-     */
-    private void boundsCheck(long f) throws InvalidDatatypeFacetException {
-        boolean inUpperBound = false;
-        boolean inLowerBound = false;
-
-        if ( isMaxInclusiveDefined ) {
-            inUpperBound = ( f <= fMaxInclusive );
-        } else if ( isMaxExclusiveDefined ) {
-            inUpperBound = ( f <  fMaxExclusive );
-        }
-
-        if ( isMinInclusiveDefined ) {
-            inLowerBound = ( f >= fMinInclusive );
-        } else if ( isMinExclusiveDefined ) {
-            inLowerBound = ( f >  fMinExclusive );
-        }
-
-        if ( inUpperBound == false  || inLowerBound == false ) { // within bounds ?
-            throw new InvalidDatatypeFacetException(
-                                                   getErrorString(DatatypeMessageProvider.OutOfBounds,
-                                                                  DatatypeMessageProvider.MSG_NONE,
-                                                                  new Object [] { new Long(f),"","","",""}));//REVISIT
-        }
-    }
-
-    private void enumCheck(long d) throws InvalidDatatypeValueException {
-        for (int i = 0; i < this.fEnumTimeDuration.length; i++) {
-            if (d == fEnumTimeDuration[i]) return;
-        }
-        throw new InvalidDatatypeValueException(
-			getErrorString(DatatypeMessageProvider.NotAnEnumValue,
-				       	   DatatypeMessageProvider.MSG_NONE,
-				       	   new Object [] { new Long( d ) }));
-    }
-
-
-
-
-    private String getErrorString(int major, int minor, Object args[]) {
-        try {
-            return fMessageProvider.createMessage(fLocale, major, minor, args);
-        } catch (Exception e) {
-            return "Illegal Errorcode "+minor;
-        }
-    }
-
-
-    private static final int indexOf(char[] value, int start, char s)
-    {
-        return(indexOf(value,start,s,value.length-1));
-    }
-    private static final int indexOf(char[] value, int start, char s, int max)
-    {
-        for (int i=start;i<=max;i++)if (value[i]==s) return(i);
-        return(-1);
-    }
-    private static final int indexOneOf(char[] value, int start, String s)
-    {
-        return(indexOneOf(value,start,s,value.length-1));
-    }
-    private static final int indexOneOf(char[] value, int start, String s, int max)
-    {
-        for (int i=start;i<max;i++)
-            for (int j=0;j<s.length();j++) if (value[i] == s.charAt(j))return(i);
-        return(-1);
-    }
-//     parseInt is a copy of the Integer.parseInt method, modified to accept
-// a character array.
-    private static final int parseInt(char[] s, int start, int length)     throws NumberFormatException
-    {
-        if (s == null) throw new NumberFormatException("null");
-        int radix=10;
-        int result = 0;
-        boolean negative = false;
-        int i= start;
-        int limit;
-        int multmin;
-        int digit=0;
-
-        if (length <= 0) throw new NumberFormatException(new String(s,start,length));
-        if (s[i] == '-')
-        {
-            negative = true;
-            limit = Integer.MIN_VALUE;
-            i++;
-        } else if (s[i]=='+')
-        {
-            negative = false;
-            limit = -Integer.MAX_VALUE;
-            i++;
-        } else
-        {
-            limit = -Integer.MAX_VALUE;
-        }
-        multmin = limit / radix;
-        if (i < (start+length))
-        {
-            digit = Character.digit(s[i++],radix);
-            if (digit < 0) throw new NumberFormatException(new String(s,start,length));
-            else result = -digit;
-        }
-        while (i < (start+length))
-        {
-            digit = Character.digit(s[i++],radix);
-            if (digit < 0) throw new NumberFormatException(new String(s,start,length));
-            if (result < multmin) throw new NumberFormatException(new String(s,start,length));
-            result *= radix;
-            if (result < limit + digit) throw new NumberFormatException(new String(s,start,length));
-            result -= digit;
-        }
-
-        if (negative)
-        {
-            if (i > 1) return result;
-            else throw new NumberFormatException(new String(s,start,length));
-        }
-        return -result;
-
-
-
-    }
-
-}
-
diff --git a/src/org/apache/xerces/validators/datatype/URIReferenceDatatypeValidator.java b/src/org/apache/xerces/validators/datatype/URIReferenceDatatypeValidator.java
deleted file mode 100644
index e9989a6..0000000
--- a/src/org/apache/xerces/validators/datatype/URIReferenceDatatypeValidator.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.datatype;
-
-import java.util.Hashtable;
-import java.util.Locale;
-import java.util.Vector;
-import java.util.Enumeration;
-import java.util.StringTokenizer;
-import java.util.NoSuchElementException;
-import org.apache.xerces.utils.URI;
-import org.apache.xerces.validators.schema.SchemaSymbols;
-import org.apache.xerces.utils.regex.RegularExpression;
-
-
-
-/**
- * URIValidator validates that XML content is a W3C uri type,
- * according to RFC 2396
- * 
- * @author Ted Leung
- * @author Jeffrey Rodriguez
- * @see          RFC 2396 
- * @see Tim Berners-Lee, et. al. RFC 2396: Uniform Resource Identifiers (URI): Generic Syntax.. 1998 Available at: http://www.ietf.org/rfc/rfc2396.txt 
- * @version  $Id$
- */
-public class URIReferenceDatatypeValidator extends AbstractDatatypeValidator {
-    private DatatypeValidator fBaseValidator     = null;
-    private boolean fDerivedByList               = false;
-
-    private int       fLength          = 0;
-    private int       fMaxLength       = Integer.MAX_VALUE;
-    private int       fMinLength       = 0;
-    private String    fPattern         = null;
-    private Vector    fEnumeration     = null;
-    private int       fFacetsDefined   = 0;
-    private RegularExpression    fRegex = null;
-
-
-
-    public URIReferenceDatatypeValidator () throws InvalidDatatypeFacetException{
-        this ( null, null, false ); // Native, No Facets defined, Restriction
-    }
-
-    public URIReferenceDatatypeValidator ( DatatypeValidator base, Hashtable facets, 
-                                           boolean derivedByList ) throws InvalidDatatypeFacetException {
-        fDerivedByList = derivedByList;
-
-        setBasetype( base ); // Set base type 
-
-        // Set Facets if any defined
-        if ( facets != null  ){
-            if ( fDerivedByList == false) {
-                for (Enumeration e = facets.keys(); e.hasMoreElements();) {
-                    String key = (String) e.nextElement();
-
-                    if ( key.equals(SchemaSymbols.ELT_LENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_LENGTH;
-                        String lengthValue = (String)facets.get(key);
-                        try {
-                            fLength     = Integer.parseInt( lengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"' is invalid.");
-                        }
-                        if ( fLength < 0 )
-                            throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"'  must be a nonNegativeInteger.");
-
-                    } else if (key.equals(SchemaSymbols.ELT_MINLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MINLENGTH;
-                        String minLengthValue = (String)facets.get(key);
-                        try {
-                            fMinLength     = Integer.parseInt( minLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("maxLength value '"+minLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MAXLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXLENGTH;
-                        String maxLengthValue = (String)facets.get(key);
-                        try {
-                            fMaxLength     = Integer.parseInt( maxLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("maxLength value '"+maxLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_PATTERN)) {
-                        fFacetsDefined += DatatypeValidator.FACET_PATTERN;
-                        fPattern = (String)facets.get(key);
-                        if ( fPattern != null )
-                            fRegex = new RegularExpression(fPattern, "X" );
-
-                    } else if (key.equals(SchemaSymbols.ELT_ENUMERATION)) {
-                        fFacetsDefined += DatatypeValidator.FACET_ENUMERATION;
-                        fEnumeration = (Vector)facets.get(key);
-                    } else {
-                        throw new InvalidDatatypeFacetException();
-                    }
-                }
-
-                if (((fFacetsDefined & DatatypeValidator.FACET_LENGTH ) != 0 ) ) {
-                    if (((fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and maxLength to be members of facets." );  
-                    } else if (((fFacetsDefined & DatatypeValidator.FACET_MINLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and minLength to be members of facets." );
-                    }
-                }
-
-                if ( ( (fFacetsDefined & ( DatatypeValidator.FACET_MINLENGTH |
-                                           DatatypeValidator.FACET_MAXLENGTH) ) != 0 ) ) {
-                    if ( fMinLength > fMaxLength ) {
-                        throw new InvalidDatatypeFacetException( "Value of maxLength = " + fMaxLength +
-                                                                 "must be greater that the value of minLength" + fMinLength );
-                    }
-                }
-            } else { //derived by list
-                for (Enumeration e = facets.keys(); e.hasMoreElements();) {
-                    String key = (String) e.nextElement();
-                    if ( key.equals(SchemaSymbols.ELT_LENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_LENGTH;
-                        String lengthValue = (String)facets.get(key);
-                        try {
-                            fLength     = Integer.parseInt( lengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"' is invalid.");
-                        }
-                        if ( fLength < 0 )
-                            throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"'  must be a nonNegativeInteger.");
-
-                    } else if (key.equals(SchemaSymbols.ELT_MINLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MINLENGTH;
-                        String minLengthValue = (String)facets.get(key);
-                        try {
-                            fMinLength     = Integer.parseInt( minLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("maxLength value '"+minLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_MAXLENGTH) ) {
-                        fFacetsDefined += DatatypeValidator.FACET_MAXLENGTH;
-                        String maxLengthValue = (String)facets.get(key);
-                        try {
-                            fMaxLength     = Integer.parseInt( maxLengthValue );
-                        } catch (NumberFormatException nfe) {
-                            throw new InvalidDatatypeFacetException("maxLength value '"+maxLengthValue+"' is invalid.");
-                        }
-                    } else if (key.equals(SchemaSymbols.ELT_ENUMERATION)) {
-                        fFacetsDefined += DatatypeValidator.FACET_ENUMERATION;
-                        fEnumeration    = (Vector)facets.get(key);
-                    } else {
-                        throw new InvalidDatatypeFacetException();
-                    }
-                }
-                if (((fFacetsDefined & DatatypeValidator.FACET_LENGTH ) != 0 ) ) {
-                    if (((fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and maxLength to be members of facets." );  
-                    } else if (((fFacetsDefined & DatatypeValidator.FACET_MINLENGTH ) != 0 ) ) {
-                        throw new InvalidDatatypeFacetException(
-                                                               "It is an error for both length and minLength to be members of facets." );
-                    }
-                }
-
-                if ( ( (fFacetsDefined & ( DatatypeValidator.FACET_MINLENGTH |
-                                           DatatypeValidator.FACET_MAXLENGTH) ) != 0 ) ) {
-                    if ( fMinLength > fMaxLength ) {
-                        throw new InvalidDatatypeFacetException( "Value of maxLength = " + fMinLength +
-                                                                 "must be greater that the value of minLength" + fMaxLength );
-                    }
-                }
-            }
-        }// End of Facets Setting
-
-    }
-
-
-
-    /**
-     * Validates content to conform to a URIReference
-     * definition and to conform to the facets allowed
-     * for this datatype.
-     * 
-     * @param content
-     * @param state
-     * @return 
-     * @exception InvalidDatatypeValueException
-     */
-    public Object validate(String content, Object state) 
-    throws InvalidDatatypeValueException
-    {
-        StringTokenizer parsedList = null;
-        URI             uriContent = null;
-
-        if ( fDerivedByList == true  ) { //derived by list
-
-
-            parsedList = new StringTokenizer( content );
-            try {
-                while ( parsedList.hasMoreTokens() ) {
-                    //checkContentList( parsedList.nextToken() ); TODO
-                }
-            } catch ( NoSuchElementException e ) {
-                e.printStackTrace();
-            }
-        } else { //derived by constraint
-            // 
-            if ( (fFacetsDefined & DatatypeValidator.FACET_PATTERN ) != 0 ) {
-                if ( fRegex == null || fRegex.matches( content) == false )
-                    throw new InvalidDatatypeValueException("Value '"+content+
-                                                            "' does not match regular expression facet" + fPattern );
-            }
-
-           
-            try {
-                uriContent = new URI( content );
-                
-            } catch (  URI.MalformedURIException ex ) {
-                throw new InvalidDatatypeValueException("Value '"+content+
-                                                                           "' is a Malformed URI ");
-
-            }
-
-
-            // checkContent( content ); TODO
-        }
-        return null;
-    }
-
-
-
-    /**
-     * Compares two URIReferences for equality.
-     * This is not really well defined.
-     * 
-     * @param content1
-     * @param content2
-     * @return 
-     */
-    public int compare( String content1, String content2){
-        return 0;
-    }
-    /**
-     * 
-     * @return Returns a Hashtable containing the facet information
-     *         for this datatype.
-     */
-    public Hashtable getFacets(){
-        return null;
-    }
-
-    /**
-   * Returns a copy of this object.
-   */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
-    }
-
-
-    // Private methods starts here
-
-    private void setBasetype(DatatypeValidator base) {
-        fBaseValidator = base;
-    }
-
-
-}
diff --git a/src/org/apache/xerces/validators/datatype/XMLException.java b/src/org/apache/xerces/validators/datatype/XMLException.java
deleted file mode 100644
index 4299b9e..0000000
--- a/src/org/apache/xerces/validators/datatype/XMLException.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.xerces.validators.datatype;
-
-
-/**
- * 
- * @author Jeffrey Rodriguez
- * @version $Id$
- */
-public class XMLException extends Exception {
-
-    public XMLException ( ) {
-    }
-
-    public XMLException ( String message ) {
-        super(message);
-    }
-    public XMLException ( Exception exception ) {
-    }
-    public XMLException ( String message, Exception exception ) {
-    }
-    public Exception getException ( ) {
-        return null;
-    }
-}
diff --git a/src/org/apache/xerces/validators/dtd/DTDGrammar.java b/src/org/apache/xerces/validators/dtd/DTDGrammar.java
deleted file mode 100644
index bf61105..0000000
--- a/src/org/apache/xerces/validators/dtd/DTDGrammar.java
+++ /dev/null
@@ -1,963 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.dtd;
-
-import org.apache.xerces.dom.DocumentImpl;
-import org.apache.xerces.framework.XMLContentSpec;
-import org.apache.xerces.framework.XMLDTDScanner;
-import org.apache.xerces.readers.XMLEntityHandler;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.validators.common.Grammar;
-import org.apache.xerces.validators.common.XMLAttributeDecl;
-import org.apache.xerces.validators.common.XMLElementDecl;
-import org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
-import org.apache.xerces.validators.schema.XUtil;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.ProcessingInstruction;
-import org.w3c.dom.Text;
-
-/**
- * A DTD grammar. This class is an EventHandler to receive callbacks from
- * the XMLDTDScanner. When the callbacks are received, the grammar structures
- * are directly populated from the callback information.
- * <p>
- * In addition to being a recipient of scanner callbacks, the DTD grammar
- * class can act as a pass-through filter for the DTD events. This is useful
- * for parsers that must expose the DTD information to the application. (e.g.
- * SAX2 DeclHandler callbacks.)
- *
- * @author Andy Clark
- * @version $Id$
- */
-public class DTDGrammar
-    extends Grammar 
-    implements XMLDTDScanner.EventHandler {
-
-    // REVISIT: The grammar access currently implemented in this grammar
-    //          instance is a draft implementation and should be revisited
-    //          in order to design a proper DTD for the this grammar
-    //          representation. -Ac
-
-    //
-    // Constants
-    //
-
-    /** Chunk shift. */
-    private static final int CHUNK_SHIFT = 8; // 2^8 = 256
-
-    /** Chunk size. */
-    private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
-
-    /** Chunk mask. */
-    private static final int CHUNK_MASK = CHUNK_SIZE - 1;
-
-    /** Initial chunk count. */
-    private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
-
-    //
-    // Data
-    //
-
-    // string pool
-
-    /** String pool. */
-    private StringPool fStringPool;
-
-    // "compiled" information structures
-
-    /** Element declaration. */
-    private XMLElementDecl fElementDecl = new XMLElementDecl();
-
-    /** Attribute declaration. */
-    private XMLAttributeDecl fAttributeDecl = new XMLAttributeDecl();
-
-    /** Content spec node. */
-    private XMLContentSpec fContentSpec = new XMLContentSpec();
-
-    // grammar document
-
-    /** Grammar document. */
-    private Document fGrammarDocument;
-
-    /** Root element. */
-    private Element fRootElement;
-
-    private QName fRootElementQName = new QName();
-
-    /** Current element. */
-    private Element fCurrentElement;
-
-    // pass-through
-
-    /** flag if the elementDecl is External. */
-    private int fElementDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][];
-    /** Mapping for element declarations. */
-    private int fElementDeclMap[][] = new int[INITIAL_CHUNK_COUNT][];
-
-    /** flag if the AttributeDecl is External. */
-    private int fAttributeDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][];
-    /** Mapping for attribute declarations. */
-    private int fAttributeDeclMap[][] = new int[INITIAL_CHUNK_COUNT][];
-
-    /** Mapping for content spec nodes. */
-    private int fContentSpecMap[][] = new int[INITIAL_CHUNK_COUNT][];
-
-    // temp vars
-
-    private QName fQName = new QName();
-
-    //
-    // Constructors
-    //
-
-    /** Default constructor. */
-    public DTDGrammar(StringPool stringPool) {
-        reset(stringPool);
-    }
-
-    //
-    // Public methods
-    //
-
-    /** Resets the DTD grammar. */
-    public void reset(StringPool stringPool) {
-        fStringPool = stringPool;
-    }
-
-    //
-    // XMLDTDScanner.EventHandler methods
-    //
-
-    /** Start of DTD. */
-    public void callStartDTD() throws Exception {
-        
-        // setup grammar document
-        setGrammarDocument(null);
-        fGrammarDocument = new DocumentImpl();
-        fRootElement = fGrammarDocument.createElement("dtd");
-        fCurrentElement = fRootElement;
-
-    } // callStartDTD()
-
-    /** End of DTD. */
-    public void callEndDTD() throws Exception {
-
-        // set grammar document
-        setGrammarDocument(fGrammarDocument);
-
-    } // callEndDTD()
-
-    /**
-     * Signal the Text declaration of an external entity.
-     *
-     * @param version the handle in the string pool for the version number
-     * @param encoding the handle in the string pool for the encoding
-     * @exception java.lang.Exception
-     */
-    public void callTextDecl(int version, int encoding) throws Exception {
-
-        // create text decl
-        Element textDecl = fGrammarDocument.createElement("textDecl");
-        textDecl.setAttribute("version", fStringPool.toString(version));
-        textDecl.setAttribute("encoding", fStringPool.toString(encoding));
-        fCurrentElement.appendChild(textDecl);
-
-    } // callTextDecl(int,int)
-
-    /**
-     * Called when the doctype decl is scanned
-     *
-     * @param rootElementType handle of the rootElement
-     * @param publicId StringPool handle of the public id
-     * @param systemId StringPool handle of the system id
-     * @exception java.lang.Exception
-     */
-    public void doctypeDecl(QName rootElement, int publicId, int systemId) 
-        throws Exception {
-
-        // create doctype decl
-        Element doctypeDecl = fGrammarDocument.createElement("doctypeDecl");
-        doctypeDecl.setAttribute("name", fStringPool.toString(rootElement.rawname));
-        if (rootElement.uri != -1) {
-            doctypeDecl.setAttribute("xmlns:"+fStringPool.toString(rootElement.prefix),
-                                     fStringPool.toString(rootElement.uri));
-        }
-        doctypeDecl.setAttribute("publicId", fStringPool.toString(publicId));
-        doctypeDecl.setAttribute("systemId", fStringPool.toString(systemId));
-        fCurrentElement.appendChild(doctypeDecl);
-
-        //fRootElementQName.setValues(-1, rootElement.rawname, -1, -1);
-        fRootElementQName.setValues(rootElement);
-
-    } // doctypeDecl(QName,int,int);
-
-    /**
-     * Called when the DTDScanner starts reading from the external subset
-     *
-     * @param publicId StringPool handle of the public id
-     * @param systemId StringPool handle of the system id
-     * @exception java.lang.Exception
-     */
-    public void startReadingFromExternalSubset(int publicId, int systemId) 
-        throws Exception {
-
-        // create external subset
-        Element externalSubset = fGrammarDocument.createElement("external");
-        externalSubset.setAttribute("publicId", fStringPool.toString(publicId));
-        externalSubset.setAttribute("systemId", fStringPool.toString(systemId));
-        fCurrentElement.appendChild(externalSubset);
-        fCurrentElement = externalSubset;
-
-    } // startReadingFromExternalSubset(int,int)
-
-    /**
-     * Called when the DTDScanner stop reading from the external subset
-     *
-     * @exception java.lang.Exception
-     */
-    public void stopReadingFromExternalSubset() throws Exception {
-
-        // get out of external subset
-        fCurrentElement = (Element)fCurrentElement.getParentNode();
-
-    } // stopReadingFromExternalSubset()
-
-    /**
-     * Add an element declaration (forward reference)
-     *
-     * @param handle to the name of the element being declared
-     * @return handle to the element whose declaration was added
-     * @exception java.lang.Exception
-     */
-    public int addElementDecl(QName elementDecl) throws Exception {
-
-        // create element decl element
-        Element elementDeclElement = fGrammarDocument.createElement("elementDecl");
-        elementDeclElement.setAttribute("name", fStringPool.toString(elementDecl.localpart));
-        if (elementDecl.uri != -1) {
-            elementDeclElement.setAttribute("xmlns:"+fStringPool.toString(elementDecl.prefix),
-                                            fStringPool.toString(elementDecl.uri));
-        }
-        fCurrentElement.appendChild(elementDeclElement);
-
-        // create element decl
-        int elementDeclIndex = createElementDecl();
-
-        // set element decl values
-        fElementDecl.clear();
-        fElementDecl.name.setValues(elementDecl);
-        setElementDecl(elementDeclIndex, fElementDecl);
-
-        // return index
-        return elementDeclIndex;
-
-    } // addElementDecl(QName):int
-
-    /**
-     * Add an element declaration
-     *
-     * @param handle to the name of the element being declared
-     * @param contentSpecType handle to the type name of the content spec
-     * @param ContentSpec handle to the content spec node for the contentSpecType
-     * @return handle to the element declaration that was added 
-     * @exception java.lang.Exception
-     */
-    public int addElementDecl(QName elementDecl, 
-                              int contentSpecType, 
-                              int contentSpec,
-                              boolean isExternal) throws Exception {
-
-        // create element decl element
-        Element elementDeclElement = fGrammarDocument.createElement("elementDecl");
-        elementDeclElement.setAttribute("name", fStringPool.toString(elementDecl.localpart));
-        if (elementDecl.uri != -1) {
-            elementDeclElement.setAttribute("xmlns:"+fStringPool.toString(elementDecl.prefix),
-                                            fStringPool.toString(elementDecl.uri));
-        }
-        elementDeclElement.setAttribute("type", fStringPool.toString(contentSpecType));
-        // REVISIT: Traverse content spec structure, building content model
-        //          description to put into grammar document.
-        fCurrentElement.appendChild(elementDeclElement);
-
-        // create element decl
-        int elementDeclIndex = createElementDecl();
-
-        // set element decl values
-        fElementDecl.clear();
-        fElementDecl.name.setValues(elementDecl);
-        fElementDecl.type = contentSpecType;
-        fElementDecl.contentSpecIndex = contentSpec;
-        setElementDecl(elementDeclIndex, fElementDecl);
-        
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        ensureElementDeclCapacity(chunk);
-        fElementDeclIsExternal[chunk][index] = isExternal? 1 : 0;
-
-        // return index
-        return elementDeclIndex;
-
-    } // addElementDecl(QName,int,int):int
-
-    protected void putElementNameMapping(QName name, int scope,
-                                         int elementDeclIndex) {
-        fQName.uri = -1;
-        fQName.localpart = name.rawname;
-        super.putElementNameMapping(fQName, scope, elementDeclIndex);
-    }
-
-    /***
-    public int getElementDeclIndex(int localpartIndex, int scopeIndex) {
-        //System.out.println("getElementDeclIndex: "+localpartIndex+", "+scopeIndex);
-        return super.getElementDeclIndex(localpartIndex, scopeIndex);
-    }
-
-    public int getElementDeclIndex(int uriIndex, int localpartIndex, int scopeIndex) {
-        //System.out.println("!!! getElementDeclIndex: "+uriIndex+", "+localpartIndex+", "+scopeIndex);
-        return super.getElementDeclIndex(localpartIndex, -1);
-    }
-    /***/
-    
-    public int getElementDeclIndex(QName element, int scopeIndex) {
-        //System.out.println("getElementDeclIndex: "+element+", "+scopeIndex);
-        return super.getElementDeclIndex(element.rawname, -1);
-    }
-
-    public void setElementDeclDTD(int elementDeclIndex, XMLElementDecl elementDecl) {
-        super.setElementDecl(elementDeclIndex, elementDecl);
-    }
-
-    private XMLContentSpec fTempContentSpec = new XMLContentSpec();
-
-    /***
-    public void setContentSpecLeaf(int contentSpecIndex, QName elementName) {
-        fTempContentSpec.setValues(XMLContentSpec.CONTENTSPECNODE_LEAF, elementName.rawname, -1);
-        super.setContentSpec(contentSpecIndex, fTempContentSpec);
-    }
-    /***/
-
-    public void setElementDeclIsExternal(int elementDeclIndex, boolean  isExternal) {
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        ensureElementDeclCapacity(chunk);
-        fElementDeclIsExternal[chunk][index] = isExternal? 1 : 0;
-    }
-
-    // getters for isExternals 
-    public boolean getElementDeclIsExternal(int elementDeclIndex) {
-        if (elementDeclIndex < 0) {
-            return false;
-        }
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        return (fElementDeclIsExternal[chunk][index] != 0);
-    }
-
-    public boolean getAttributeDeclIsExternal(int attributeDeclIndex) {
-        if (attributeDeclIndex < 0) {
-            return false;
-        }
-        int chunk = attributeDeclIndex >> CHUNK_SHIFT;
-        int index = attributeDeclIndex & CHUNK_MASK;
-        return (fAttributeDeclIsExternal[chunk][index] != 0);
-    }
-
-    public boolean getRootElementQName(QName root) {
-        if (fRootElementQName.rawname == -1) {
-            return false;
-        }
-        root.setValues(fRootElementQName);
-        return true;
-    }
-
-    /**
-     * Add an attribute definition
-     *
-     * @param handle to the element whose attribute is being declared
-     * @param attName StringPool handle to the attribute name being declared
-     * @param attType type of the attribute
-     * @param enumeration StringPool handle of the attribute's enumeration list (if any)
-     * @param attDefaultType an integer value denoting the DefaultDecl value
-     * @param attDefaultValue StringPool handle of this attribute's default value
-     * @return handle to the attribute definition
-     * @exception java.lang.Exception
-     */
-    public int addAttDef(QName elementDecl, QName attributeDecl, 
-                         int attType, boolean attList, int enumeration, 
-                         int attDefaultType, int attDefaultValue, boolean isExternal) 
-        throws Exception {
-        /****
-        System.out.println("---add attr--- "+attributeDecl.localpart
-                  +","+attType        
-                  +","+attDefaultType        
-                  +","+isExternal);
-         /****/
-
-        // create attribute decl element
-        Element attributeDeclElement = fGrammarDocument.createElement("attributeDecl");
-        attributeDeclElement.setAttribute("element", fStringPool.toString(elementDecl.localpart));
-        attributeDeclElement.setAttribute("name", fStringPool.toString(attributeDecl.localpart));
-        if (attributeDecl.uri != -1) {
-            attributeDeclElement.setAttribute("xmlns:"+fStringPool.toString(attributeDecl.prefix),
-                                              fStringPool.toString(attributeDecl.uri));
-        }
-        attributeDeclElement.setAttribute("type", fStringPool.toString(attType));
-        // REVISIT: Add enumeration information to grammar document.
-        // REVISIT: Do the default type, value better.
-        attributeDeclElement.setAttribute("defaultType", fStringPool.toString(attDefaultType));
-        attributeDeclElement.setAttribute("defaultValue", fStringPool.toString(attDefaultValue));
-        fCurrentElement.appendChild(attributeDeclElement);
-
-        // create attribute decl
-        int attributeDeclIndex = createAttributeDecl();
-
-        // find the dataTypeValidator associcated with this attType
-        String attTypeString = "";
-        switch (attType) {
-        case XMLAttributeDecl.TYPE_CDATA:
-            attTypeString = "string";
-        case XMLAttributeDecl.TYPE_ENTITY:
-            attTypeString = "ENTITY";;
-        case XMLAttributeDecl.TYPE_ENUMERATION:
-            attTypeString = "ENUMERATION";;
-        case XMLAttributeDecl.TYPE_ID:
-            attTypeString = "ID";;
-        case XMLAttributeDecl.TYPE_IDREF:
-            attTypeString = "IDREF";;
-        case XMLAttributeDecl.TYPE_NMTOKEN:
-            attTypeString = "NMTOKEN";;
-        case XMLAttributeDecl.TYPE_NOTATION:
-            attTypeString = "NOTATION";;
-        default:
-            ;
-        }
-
-        // set attribute decl values
-        fAttributeDecl.clear();
-        fAttributeDecl.name.setValues(attributeDecl);
-        fAttributeDecl.type = attType;
-        fAttributeDecl.list = attList;
-        fAttributeDecl.enumeration = enumeration;
-        fAttributeDecl.datatypeValidator = 
-            DatatypeValidatorFactoryImpl.getDatatypeRegistry().getDatatypeValidator(attTypeString);
-        // REVISIT: Don't forget the enumeration
-        fAttributeDecl.defaultType = attDefaultType;
-        fAttributeDecl.defaultValue = fStringPool.toString(attDefaultValue);
-
-        int elementDeclIndex = getElementDeclIndex(elementDecl, -1);
-        setAttributeDecl(elementDeclIndex, attributeDeclIndex, fAttributeDecl);
-
-        int chunk = attributeDeclIndex >> CHUNK_SHIFT;
-        int index = attributeDeclIndex & CHUNK_MASK;
-        ensureAttributeDeclCapacity(chunk);
-        fAttributeDeclIsExternal[chunk][index] = isExternal ?  1 : 0;
-
-        // return index
-        return attributeDeclIndex;
-
-    } // addAttDef(QName,QName,int,int,int,int):int
-
-    /**
-     * create an XMLContentSpec for a leaf
-     *
-     * @param nameIndex StringPool handle to the name (Element) for the node
-     * @return handle to the newly create XMLContentSpec
-     * @exception java.lang.Exception
-     */
-    public int addUniqueLeafNode(int nameIndex) throws Exception {
-
-        // create content spec node
-        int contentSpecIndex = createContentSpec();
-
-        // set content spec node values
-        fContentSpec.setValues(XMLContentSpec.CONTENTSPECNODE_LEAF, 
-                               nameIndex, -1);
-        setContentSpec(contentSpecIndex, fContentSpec);
-
-        // return index 
-        return contentSpecIndex;
-
-    } // addUniqueLeafNode(int):int
-
-    /**
-     * Create an XMLContentSpec for a single non-leaf
-     * 
-     * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
-     * @param nodeValue handle to an XMLContentSpec
-     * @return handle to the newly create XMLContentSpec
-     * @exception java.lang.Exception
-     */
-    public int addContentSpecNode(int nodeType, 
-                                  int nodeValue) throws Exception {
-
-        // create content spec node
-        int contentSpecIndex = createContentSpec();
-
-        // set content spec node values
-        fContentSpec.setValues(nodeType, nodeValue, -1);
-        setContentSpec(contentSpecIndex, fContentSpec);
-
-        // return index 
-        return contentSpecIndex;
-
-    } // addContentSpecNode(int,int):int
-
-    /**
-     * Create an XMLContentSpec for a two child leaf
-     *
-     * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
-     * @param leftNodeIndex handle to an XMLContentSpec
-     * @param rightNodeIndex handle to an XMLContentSpec
-     * @return handle to the newly create XMLContentSpec
-     * @exception java.lang.Exception
-     */
-    public int addContentSpecNode(int nodeType, 
-                                  int leftNodeIndex, 
-                                  int rightNodeIndex) throws Exception {
-
-        // create content spec node
-        int contentSpecIndex = createContentSpec();
-
-        // set content spec node values
-        fContentSpec.setValues(nodeType, 
-                               leftNodeIndex, rightNodeIndex);
-        setContentSpec(contentSpecIndex, fContentSpec);
-
-        // return index 
-        return contentSpecIndex;
-
-    } // addContentSpecNode(int,int,int):int
-
-    /**
-     * Create a string representation of an XMLContentSpec tree
-     * 
-     * @param handle to an XMLContentSpec
-     * @return String representation of the content spec tree
-     * @exception java.lang.Exception
-     */
-    public String getContentSpecNodeAsString(int nodeIndex) throws Exception {
-        return XMLContentSpec.toString(this, fStringPool, nodeIndex);
-    }
-
-    /**
-     * Start the scope of an entity declaration.
-     *
-     * @return <code>true</code> on success; otherwise
-     *         <code>false</code> if the entity declaration is recursive.
-     * @exception java.lang.Exception
-     */
-    public boolean startEntityDecl(boolean isPE, int entityName) 
-        throws Exception {
-
-        // create entity decl
-        Element entityDecl = fGrammarDocument.createElement("entityDecl");
-        entityDecl.setAttribute("name", fStringPool.toString(entityName));
-        entityDecl.setAttribute("parameter", isPE ? "true" : "false");
-        fCurrentElement.appendChild(entityDecl);
-        fCurrentElement = entityDecl;
-
-        // success
-        return true;
-
-    } // startEntityDecl(boolean,int):boolean
-
-    /**
-     * End the scope of an entity declaration.
-     * @exception java.lang.Exception
-     */
-    public void endEntityDecl() throws Exception {
-
-        // get out of entity decl
-        fCurrentElement = (Element)fCurrentElement.getParentNode();
-
-    } // endEntityDecl()
-
-    /**
-     * Add a declaration for an internal parameter entity
-     *
-     * @param name StringPool handle of the parameter entity name
-     * @param value StringPool handle of the parameter entity value
-     * @return handle to the parameter entity declaration
-     * @exception java.lang.Exception
-     */
-    public int addInternalPEDecl(int name, int value) throws Exception {
-
-        // create internal PE decl
-        Element internalPEDecl = fGrammarDocument.createElement("internalPEDecl");
-        internalPEDecl.setAttribute("name", fStringPool.toString(name));
-        internalPEDecl.setAttribute("value", fStringPool.toString(value));
-        fCurrentElement.appendChild(internalPEDecl);
-
-        // REVISIT: What is my responsibility for creating a handle?
-        int peDeclIndex = -1;
-
-        // return index
-        return peDeclIndex;
-
-    } // addInternalPEDecl(int,int):int
-
-    /**
-     * Add a declaration for an external parameter entity
-     *
-     * @param name StringPool handle of the parameter entity name
-     * @param publicId StringPool handle of the publicId
-     * @param systemId StringPool handle of the systemId
-     * @return handle to the parameter entity declaration
-     * @exception java.lang.Exception
-     */
-    public int addExternalPEDecl(int name, 
-                                 int publicId, 
-                                 int systemId) throws Exception {
-        
-        // create external PE decl
-        Element externalPEDecl = fGrammarDocument.createElement("externalPEDecl");
-        externalPEDecl.setAttribute("name", fStringPool.toString(name));
-        externalPEDecl.setAttribute("publicId", fStringPool.toString(publicId));
-        externalPEDecl.setAttribute("systemId", fStringPool.toString(systemId));
-        fCurrentElement.appendChild(externalPEDecl);
-
-        // REVISIT: What is my responsibility for creating a handle?
-        int peDeclIndex = -1;
-
-        // return index
-        return peDeclIndex;
-
-    } // addExternalPEDecl(int,int,int):int
-
-    /**
-     * Add a declaration for an internal entity
-     *
-     * @param name StringPool handle of the entity name
-     * @param value StringPool handle of the entity value
-     * @return handle to the entity declaration
-     * @exception java.lang.Exception
-     */
-    public int addInternalEntityDecl(int name, int value) throws Exception {
-
-        // create internal entity decl
-        Element internalEntityDecl = fGrammarDocument.createElement("internalEntityDecl");
-        internalEntityDecl.setAttribute("name", fStringPool.toString(name));
-        internalEntityDecl.setAttribute("value", fStringPool.toString(value));
-        fCurrentElement.appendChild(internalEntityDecl);
-            
-        // REVISIT: What is my responsibility for creating a handle?
-        int internalEntityDeclIndex = -1;
-
-        // return index
-        return internalEntityDeclIndex;
-
-    } // addInternalEntityDecl(int,int):int
-
-    /**
-     * Add a declaration for an entity
-     *
-     * @param name StringPool handle of the entity name
-     * @param publicId StringPool handle of the publicId
-     * @param systemId StringPool handle of the systemId
-     * @return handle to the entity declaration
-     * @exception java.lang.Exception
-     */
-    public int addExternalEntityDecl(int name, 
-                                     int publicId, 
-                                     int systemId) throws Exception {
-
-        // create external entity decl
-        Element externalEntityDecl = fGrammarDocument.createElement("externalEntityDecl");
-        externalEntityDecl.setAttribute("name", fStringPool.toString(name));
-        externalEntityDecl.setAttribute("publicId", fStringPool.toString(publicId));
-        externalEntityDecl.setAttribute("systemId", fStringPool.toString(systemId));
-        fCurrentElement.appendChild(externalEntityDecl);
-            
-        // REVISIT: What is my responsibility for creating a handle?
-        int externalEntityDeclIndex = -1;
-
-        // return index
-        return externalEntityDeclIndex;
-
-    } // addExternalEntityDecl(int,int,int):int
-
-    /**
-     * Add a declaration for an unparsed entity
-     *
-     * @param name StringPool handle of the entity name
-     * @param publicId StringPool handle of the publicId
-     * @param systemId StringPool handle of the systemId
-     * @param notationName StringPool handle of the notationName
-     * @return handle to the entity declaration
-     * @exception java.lang.Exception
-     */
-    public int addUnparsedEntityDecl(int name, 
-                                     int publicId, int systemId, 
-                                     int notationName) throws Exception {
-
-        // create external entity decl
-        Element unparsedEntityDecl = fGrammarDocument.createElement("unparsedEntityDecl");
-        unparsedEntityDecl.setAttribute("name", fStringPool.toString(name));
-        unparsedEntityDecl.setAttribute("publicId", fStringPool.toString(publicId));
-        unparsedEntityDecl.setAttribute("systemId", fStringPool.toString(systemId));
-        unparsedEntityDecl.setAttribute("notation", fStringPool.toString(notationName));
-        fCurrentElement.appendChild(unparsedEntityDecl);
-            
-        // REVISIT: What is my responsibility for creating a handle?
-        int unparsedEntityDeclIndex = -1;
-
-        // return index
-        return unparsedEntityDeclIndex;
-
-    } // addUnparsedEntityDecl(int,int,int,int):int
-
-    /**
-     * Called when the scanner start scanning an enumeration
-     * @return StringPool handle to a string list that will hold the enumeration names
-     * @exception java.lang.Exception
-     */
-    public int startEnumeration() throws Exception {
-            
-        // create enumeration
-        Element enumeration = fGrammarDocument.createElement("enumeration");
-        fCurrentElement.appendChild(enumeration);
-        fCurrentElement = enumeration;
-
-        // REVISIT: What is my responsibility for creating a handle?
-        //int enumIndex = -1;    
-        int enumIndex = fStringPool.startStringList();
-
-        // return index
-        return enumIndex;
-
-    } // startEnumeration():int
-
-    /**
-     * Add a name to an enumeration
-     * @param enumIndex StringPool handle to the string list for the enumeration
-     * @param elementType handle to the element that owns the attribute with the enumeration
-     * @param attrName StringPool handle to the name of the attribut with the enumeration
-     * @param nameIndex StringPool handle to the name to be added to the enumeration
-     * @param isNotationType true if the enumeration is an enumeration of NOTATION names
-     * @exception java.lang.Exception
-     */
-    public void addNameToEnumeration(int enumIndex, 
-                                     int elementType, int attrName, 
-                                     int nameIndex, 
-                                     boolean isNotationType) throws Exception {
-        
-        // create enumeration literal
-        Element literal = fGrammarDocument.createElement("literal");
-        // REVISIT: How is this literal (and its parent enumeration)
-        //          associated to an element and attribute name? This
-        //          should be done better.
-        literal.setAttribute("element", fStringPool.toString(elementType));
-        literal.setAttribute("attribute", fStringPool.toString(attrName));
-        literal.setAttribute("name", fStringPool.toString(nameIndex));
-        literal.setAttribute("notation", isNotationType ? "true" : "false");
-        fCurrentElement.appendChild(literal);
-
-        //add the name to the stringList 
-        fStringPool.addStringToList(enumIndex, nameIndex);
-
-    } // addNameToEnumeration(int,int,int,int,boolean)
-
-    /**
-     * Finish processing an enumeration
-     *
-     * @param enumIndex handle to the string list which holds the enumeration to be finshed.
-     * @exception java.lang.Exception
-     */
-    public void endEnumeration(int enumIndex) throws Exception {
-
-        // get out of enumeration
-        fCurrentElement = (Element)fCurrentElement.getParentNode();
-        
-        //finish the enumeration stringlist int the fStringPool
-        fStringPool.finishStringList(enumIndex);
-
-    } // endEnumeration(int)
-
-    /**
-     * Add a declaration for a notation
-     *
-     * @param notationName
-     * @param publicId
-     * @param systemId
-     * @return handle to the notation declaration
-     * @exception java.lang.Exception
-     */
-    public int addNotationDecl(int notationName, 
-                               int publicId, int systemId) throws Exception {
-
-        // create notation decl
-        Element notationDecl = fGrammarDocument.createElement("notationDecl");
-        notationDecl.setAttribute("name", fStringPool.toString(notationName));
-        notationDecl.setAttribute("publicId", fStringPool.toString(publicId));
-        notationDecl.setAttribute("systemId", fStringPool.toString(systemId));
-        fCurrentElement.appendChild(notationDecl);
-
-        // REVISIT: What is my responsibility for creating a handle?
-        int notationDeclIndex = -1;
-
-        // return index
-        return notationDeclIndex;
-
-    } // addNotationdecl(int,int,int):int
-
-    /**
-     * Called when a comment has been scanned
-     *
-     * @param data StringPool handle of the comment text
-     * @exception java.lang.Exception
-     */
-    public void callComment(int data) throws Exception {
-    }
-
-    /**
-     * Called when a processing instruction has been scanned
-     * @param piTarget StringPool handle of the PI target
-     * @param piData StringPool handle of the PI data
-     * @exception java.lang.Exception
-     */
-    public void callProcessingInstruction(int piTarget, int piData) 
-        throws Exception {
-
-        // create pi
-        ProcessingInstruction pi = 
-            fGrammarDocument.createProcessingInstruction(fStringPool.toString(piTarget),
-                                                         fStringPool.toString(piData));
-        fCurrentElement.appendChild(pi);
-
-    } // callProcessingInstruction(int,int)
-
-    // deprecated -- removed from DOM Level 2
-
-    /**
-     * Supports DOM Level 2 internalSubset additions.
-     * Called when the internal subset is completely scanned.
-     */
-    public void internalSubset(int internalSubset) throws Exception {
-    }
-
-    protected boolean isDTD() {
-        return true;
-    }
-
-    //
-    // Private methods
-    //
-
-    // ensure capacity
-
-    /** Ensures storage for element declaration mappings. */
-    private boolean ensureElementDeclCapacity(int chunk) {
-        try {
-            return fElementDeclMap[chunk][0] == 0;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            fElementDeclMap = resize(fElementDeclMap, 
-                                     fElementDeclMap.length * 2);
-            fElementDeclIsExternal = resize(fElementDeclIsExternal, 
-                                     fElementDeclIsExternal.length * 2);
-        } catch (NullPointerException ex) {
-            // ignore
-        }
-        fElementDeclMap[chunk] = new int[CHUNK_SIZE];
-        fElementDeclIsExternal[chunk] = new int[CHUNK_SIZE];
-        return true;
-    }
-
-    /** Ensures storage for attribute declaration mappings. */
-    private boolean ensureAttributeDeclCapacity(int chunk) {
-        try {
-            return fAttributeDeclMap[chunk][0] == 0;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            fAttributeDeclMap = resize(fAttributeDeclMap, 
-                                       fAttributeDeclMap.length * 2);
-            fAttributeDeclIsExternal = resize(fAttributeDeclIsExternal, 
-                                       fAttributeDeclIsExternal.length * 2);
-        } catch (NullPointerException ex) {
-            // ignore
-        }
-        fAttributeDeclMap[chunk] = new int[CHUNK_SIZE];
-        fAttributeDeclIsExternal[chunk] = new int[CHUNK_SIZE];
-        return true;
-    }
-
-    /** Ensures storage for content spec mappings. */
-    private boolean ensureContentSpecCapacity(int chunk) {
-        try {
-            return fContentSpecMap[chunk][0] == 0;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            fContentSpecMap = resize(fContentSpecMap, 
-                                     fContentSpecMap.length * 2);
-        } catch (NullPointerException ex) {
-            // ignore
-        }
-        fContentSpecMap[chunk] = new int[CHUNK_SIZE];
-        return true;
-    }
-
-    // resize initial chunk
-
-    /** Resizes chunked integer arrays. */
-    private int[][] resize(int array[][], int newsize) {
-        int newarray[][] = new int[newsize][];
-        System.arraycopy(array, 0, newarray, 0, array.length);
-        return newarray;
-    }
-
-} // class DTDGrammar
diff --git a/src/org/apache/xerces/validators/dtd/Makefile b/src/org/apache/xerces/validators/dtd/Makefile
deleted file mode 100644
index 3e22b78..0000000
--- a/src/org/apache/xerces/validators/dtd/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# Makefile for directory ./org/apache/xerces/validators/dtd
-
-TARGETS=\
-	DTDGrammar.class
-
-DIRS = 
-
-TOP = ../../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xerces/validators/schema/EquivClassComparator.java b/src/org/apache/xerces/validators/schema/EquivClassComparator.java
deleted file mode 100644
index 4996f37..0000000
--- a/src/org/apache/xerces/validators/schema/EquivClassComparator.java
+++ /dev/null
@@ -1,156 +0,0 @@
-
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.xerces.validators.schema;
-
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.utils.StringPool;
-import org.apache.xerces.validators.common.GrammarResolver;
-
-import org.xml.sax.SAXException;
-
-import java.lang.ClassCastException;
-/* 
- * @author Eric Ye
- *         
- * @see    
- *
- * @version $Id$
- */
-
-public class EquivClassComparator {
-
-    // constants
-    private final int TOP_LEVEL_SCOPE = -1;
-
-    // private data members
-    private StringPool fStringPool = null;
-    private GrammarResolver fGrammarResolver = null;
-
-    // constructors
-    private EquivClassComparator(){
-        // can never be instantiated without passing in a GrammarResolver.
-    }
-    public  EquivClassComparator(GrammarResolver grammarResolver, StringPool stringPool){
-        fGrammarResolver = grammarResolver;
-        fStringPool = stringPool;
-    }
-
-    //public methods
-    public boolean isEquivalentTo(QName aElement, QName examplar) throws Exception{
-        if (aElement.localpart==examplar.localpart && aElement.uri==examplar.uri ) {
-            return true;
-        }
-
-        if (fGrammarResolver == null || fStringPool == null) {
-            throw new SAXException("Try to check equivalency by equivClass, but no GrammarResolver is defined");
-        }
-
-        int count = 16; // 16 is the limit of times for which we'll check the equivClass transitively.
-        int uriIndex = aElement.uri;
-        int localpartIndex = aElement.localpart;
-        String uri = fStringPool.toString(aElement.uri);
-        String localpart = fStringPool.toString(aElement.localpart);
-
-        while (count >= 0) {
-            if(uri==null) {
-                return false;
-            }
-            SchemaGrammar sGrammar = null;
-            try {
-                sGrammar = (SchemaGrammar) fGrammarResolver.getGrammar(uri);
-            }
-            catch ( ClassCastException ce) {
-                //since the returen Grammar is not a SchemaGrammar, bail out
-                return false;
-            }
-            if(sGrammar == null) return false;
-
-            int elementIndex = sGrammar.getElementDeclIndex(uriIndex, localpartIndex, TOP_LEVEL_SCOPE);
-            //System.out.println("----------equivClassFullName : " + uriIndex+","+localpartIndex+","+elementIndex);
-            if (elementIndex == -1) {
-                return false;
-            }
-
-            String equivClassFullName = sGrammar.getElementDeclEquivClassElementFullName(elementIndex);
-            //System.out.println("----------equivClassFullName : " + equivClassFullName);
-            if (equivClassFullName==null) {
-                return false;
-            }
-
-            int commaAt = equivClassFullName.indexOf(","); 
-            uri = "";
-            localpart = equivClassFullName;
-            if (  commaAt >= 0  ) {
-                if (commaAt > 0 ) {
-                    uri = equivClassFullName.substring(0,commaAt);
-                }
-                localpart = equivClassFullName.substring(commaAt+1);
-            }
-            uriIndex = fStringPool.addSymbol(uri);
-            localpartIndex = fStringPool.addSymbol(localpart);
-
-            if (uriIndex == examplar.uri && localpartIndex == examplar.localpart) {
-                return true;
-            }
-
-            count--;
-        }
-
-        return false;
-    }
-}
diff --git a/src/org/apache/xerces/validators/schema/Makefile b/src/org/apache/xerces/validators/schema/Makefile
deleted file mode 100644
index 73993ba..0000000
--- a/src/org/apache/xerces/validators/schema/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# Makefile for directory ./org/apache/xerces/validators/schema
-
-TARGETS=\
-	EquivClassComparator.class\
-	SchemaGrammar.class\
-	SchemaMessageProvider.class\
-	SchemaSymbols.class \
-	TraverseSchema.class \
-	XUtil.class
-
-DIRS = 
-
-TOP = ../../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xerces/validators/schema/SchemaGrammar.java b/src/org/apache/xerces/validators/schema/SchemaGrammar.java
deleted file mode 100644
index 175bee8..0000000
--- a/src/org/apache/xerces/validators/schema/SchemaGrammar.java
+++ /dev/null
@@ -1,543 +0,0 @@
-
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
- 
- /*
- * @author Eric Ye
- *         
- * @see    
- * @version $Id$
- */
-package org.apache.xerces.validators.schema;
-
-import org.apache.xerces.framework.XMLContentSpec;
-import org.apache.xerces.utils.NamespacesScope;
-import org.apache.xerces.utils.QName;
-import org.apache.xerces.framework.XMLContentSpec;
-import org.apache.xerces.validators.datatype.DatatypeValidator;
-import org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
-import org.apache.xerces.validators.common.XMLAttributeDecl;
-import org.apache.xerces.validators.common.XMLContentModel;
-import org.apache.xerces.validators.common.XMLElementDecl;
-import org.apache.xerces.validators.common.Grammar;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import java.util.Hashtable;
-
-public class SchemaGrammar extends Grammar{
-
-    // Constants
-    //
-
-    private static final int CHUNK_SHIFT = 8; // 2^8 = 256
-    private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
-    private static final int CHUNK_MASK = CHUNK_SIZE - 1;
-    private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
-
-    //Temp objects for decls structs.
-    private XMLContentSpec fTempContentSpecNode = new XMLContentSpec();
-    private XMLElementDecl fTempElementDecl = new XMLElementDecl();
-    private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
-
-    //
-    // Data
-    //
-
-    // basic information
-
-    // private int fTargetNamespace;
-
-    // private Element fGrammarDocument;
-
-    // element decl tables that used only by Schemas
-    // these arrays are indexed by elementdeclindex.
-
-    private int fScopeDefinedByElement[][] = new int[INITIAL_CHUNK_COUNT][];
-    private String fFromAnotherSchemaURI[][] = new String[INITIAL_CHUNK_COUNT][];
-    private TraverseSchema.ComplexTypeInfo fComplexTypeInfo[][] = 
-        new TraverseSchema.ComplexTypeInfo[INITIAL_CHUNK_COUNT][];
-    private int fElementDeclDefaultType[][] = new int[INITIAL_CHUNK_COUNT][];
-    private String fElementDeclDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][];
-    private String fElementDeclEquivClassFullName[][] = new String[INITIAL_CHUNK_COUNT][];
-    private int fElementDeclBlockSet[][] = new int[INITIAL_CHUNK_COUNT][];
-    private int fElementDeclFinalSet[][] = new int[INITIAL_CHUNK_COUNT][];
-    private int fElementDeclMiscFlags[][] = new int[INITIAL_CHUNK_COUNT][];
-
-    //ComplexType and SimpleTypeRegistries
-    private Hashtable fComplexTypeRegistry = null;
-    private Hashtable fAttributeDeclRegistry = null;
-    private DatatypeValidatorFactoryImpl fDatatypeRegistry = null;
-
-    Hashtable topLevelGroupDecls = new Hashtable();
-    Hashtable topLevelAttrDecls  = new Hashtable();
-    Hashtable topLevelAttrGrpDecls = new Hashtable();
-
-    private NamespacesScope fNamespacesScope = null;
-    private String fTargetNamespaceURI = "";
-
-    //
-    // Public methods
-    //
-
-    public NamespacesScope getNamespacesScope(){
-        return fNamespacesScope;
-    }
-
-    public String getTargetNamespaceURI(){
-        return fTargetNamespaceURI;
-    }
-
-    public Hashtable getAttirubteDeclRegistry() {
-        return fAttributeDeclRegistry;
-    }
-
-    public Hashtable getComplexTypeRegistry(){
-        return fComplexTypeRegistry;
-    }
-
-    public DatatypeValidatorFactoryImpl getDatatypeRegistry(){
-        return fDatatypeRegistry;
-    }
-
-    public int getElementDefinedScope(int elementDeclIndex) {
-        
-        if (elementDeclIndex < -1) {
-            return -1;
-        }
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        return fScopeDefinedByElement[chunk][index];
-
-    }
-    
-    public int getElementDefaultTYpe(int elementDeclIndex) {
-        
-        if (elementDeclIndex < -1) {
-            return -1;
-        }
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        return fElementDeclDefaultType[chunk][index];
-
-    }
-
-    public int getElementDeclBlockSet(int elementDeclIndex) {
-
-        if (elementDeclIndex < -1) {
-            return -1;
-        }
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        return fElementDeclBlockSet[chunk][index];
-    }
-
-    public int getElementDeclFinalSet(int elementDeclIndex) {
-
-        if (elementDeclIndex < -1) {
-            return -1;
-        }
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        return fElementDeclFinalSet[chunk][index];
-    }
-
-    public int getElementDeclMiscFlags(int elementDeclIndex) {
-
-        if (elementDeclIndex < -1) {
-            return -1;
-        }
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        return fElementDeclMiscFlags[chunk][index];
-    }
-
-    public String getElementFromAnotherSchemaURI(int elementDeclIndex) {
-        
-        if (elementDeclIndex < 0 ) {
-            return null;
-        }
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        return fFromAnotherSchemaURI[chunk][index];
-
-    }
-
-    public String getElementDefaultValue(int elementDeclIndex) {
-        
-        if (elementDeclIndex < 0 ) {
-            return null;
-        }
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        return fElementDeclDefaultValue[chunk][index];
-
-    }
-    public String getElementDeclEquivClassElementFullName( int elementDeclIndex){
-        
-        if (elementDeclIndex < 0 ) {
-            return null;
-        }
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        return fElementDeclEquivClassFullName[chunk][index];
-
-    }
-
-    public TraverseSchema.ComplexTypeInfo getElementComplexTypeInfo(int elementDeclIndex){
-
-        if (elementDeclIndex <- 1) {
-            return null;
-        }
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        return fComplexTypeInfo[chunk][index];
-    }
-
-
-
-    //
-    // Protected methods
-    //
-    protected void  setAttributeDeclRegistry(Hashtable attrReg){
-        fAttributeDeclRegistry = attrReg;
-    }
-
-    protected void  setComplexTypeRegistry(Hashtable cTypeReg){
-        fComplexTypeRegistry = cTypeReg;
-    }
-
-    protected void setDatatypeRegistry(DatatypeValidatorFactoryImpl dTypeReg){
-        fDatatypeRegistry = dTypeReg;
-    }
-
-    protected void setNamespacesScope(NamespacesScope nsScope) {
-        fNamespacesScope = nsScope;
-    }
-
-    protected void setTargetNamespaceURI(String targetNSUri) {
-        fTargetNamespaceURI = targetNSUri;
-    }
-
-
-    protected int createElementDecl() {
-        return super.createElementDecl();
-    }
-
-    protected void setElementDecl(int elementDeclIndex, XMLElementDecl elementDecl) {
-        super.setElementDecl(elementDeclIndex,elementDecl);
-    }
-
-    //public int addAttributeDeclByHead(int attributeDeclIndex, int attributeListHead) {
-    //  return super.addAttributeDeclByHead(attributeDeclIndex, attributeListHead);
-    //}
-
-
-    protected int createContentSpec() {
-        return super.createContentSpec();
-    }
-
-    protected void setContentSpec(int contentSpecIndex, XMLContentSpec contentSpec) {
-        super.setContentSpec(contentSpecIndex, contentSpec);
-    }
-
-    protected int createAttributeDecl() {
-        return super.createAttributeDecl();
-    }
-
-    protected void setAttributeDecl(int elementDeclIndex, int attributeDeclIndex, XMLAttributeDecl attributeDecl) {
-        super.setAttributeDecl(elementDeclIndex, attributeDeclIndex, attributeDecl);
-    }
-
-    protected void setElementDefinedScope(int elementDeclIndex, int scopeDefined) {
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        ensureElementDeclCapacity(chunk);
-        if (elementDeclIndex > -1 ) {
-            fScopeDefinedByElement[chunk][index] = scopeDefined;
-        }
-    }
-
-    protected  void setElementFromAnotherSchemaURI(int elementDeclIndex, String anotherSchemaURI) {
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        ensureElementDeclCapacity(chunk);
-        if (elementDeclIndex > -1 ) {
-            fFromAnotherSchemaURI[chunk][index] = anotherSchemaURI;
-        }
-    }
-
-    protected void setElementComplexTypeInfo(int elementDeclIndex, TraverseSchema.ComplexTypeInfo typeInfo){
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        ensureElementDeclCapacity(chunk);
-        if (elementDeclIndex > -1 ) {
-            fComplexTypeInfo[chunk][index] = typeInfo;
-        }
-    }
-
-    protected void setElementDefault(int elementDeclIndex, int defaultType, String defaultValue) {
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        ensureElementDeclCapacity(chunk);
-        if (elementDeclIndex > -1 ) {
-            fElementDeclDefaultType[chunk][index] = defaultType;
-            fElementDeclDefaultValue[chunk][index] = defaultValue;
-        }
-    }
-    
-    protected void setElementDeclBlockSet(int elementDeclIndex, int blockSet) {
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        ensureElementDeclCapacity(chunk);
-        if (elementDeclIndex > -1 ) {
-            fElementDeclBlockSet[chunk][index] = blockSet;
-        }
-    }
-
-    protected void setElementDeclFinalSet(int elementDeclIndex, int finalSet) {
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        ensureElementDeclCapacity(chunk);
-        if (elementDeclIndex > -1 ) {
-            fElementDeclFinalSet[chunk][index] = finalSet;
-        }
-    }
-
-    protected void setElementDeclMiscFlags(int elementDeclIndex, int miscFlags) {
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        ensureElementDeclCapacity(chunk);
-        if (elementDeclIndex > -1 ) {
-            fElementDeclMiscFlags[chunk][index] = miscFlags;
-        }
-    }
-
-    protected void setElementDeclEquivClassElementFullName( int elementDeclIndex, String equivClassFullName){
-        int chunk = elementDeclIndex >> CHUNK_SHIFT;
-        int index = elementDeclIndex & CHUNK_MASK;
-        ensureElementDeclCapacity(chunk);
-        if (elementDeclIndex > -1 ) {
-            fElementDeclEquivClassFullName[chunk][index] = equivClassFullName;
-        }
-    }
-
-    //add methods for TraverseSchema
-    /**
-     *@return elementDecl Index, 
-     */
-
-    protected int addElementDecl(QName eltQName, int enclosingScope, int scopeDefined, 
-                                 int contentSpecType, int contentSpecIndex, 
-                                 int attrListHead, DatatypeValidator dv){
-        int elementDeclIndex = getElementDeclIndex(eltQName, enclosingScope);
-        if (elementDeclIndex == -1) {
-            if (enclosingScope<-1 || scopeDefined < -1 ) {
-                //TO DO: report error here;
-            }
-            fTempElementDecl.name.setValues(eltQName);
-            fTempElementDecl.enclosingScope = enclosingScope;
-            fTempElementDecl.type = contentSpecType;
-            fTempElementDecl.contentSpecIndex = contentSpecIndex;
-            fTempElementDecl.datatypeValidator = dv;
-            //fTempElementDecl.firstAttributeDeclIndex = attrListHead;
-            elementDeclIndex = createElementDecl();
-            setElementDecl(elementDeclIndex,fTempElementDecl);
-            setFirstAttributeDeclIndex(elementDeclIndex, attrListHead);
-            //note, this is the scope defined by the element, not its enclosing scope
-            setElementDefinedScope(elementDeclIndex, scopeDefined);
-        }
-
-    //debugging
-    /*****
-             XMLElementDecl fTempElementDecl = new XMLElementDecl();                                          
-             getElementDecl(elementDeclIndex, fTempElementDecl);                                              
-             System.out.println("elementDeclIndex in addElementDecl : " + elementDeclIndex                            
-                                + " \n and itsName : '"                                                               
-                                + (fTempElementDecl.name.localpart)                                       
-                                +"' \n its ContentType:" + (fTempElementDecl.type)                        
-                                +"\n its ContentSpecIndex : " + fTempElementDecl.contentSpecIndex +"\n"); 
-    /*****/
-        return elementDeclIndex;
-
-    }
-
-    /**
-     *@return the new attribute List Head
-     */
-    protected void addAttDef(  int templateElementIndex, 
-                      QName attQName, int attType, 
-                      int enumeration, int attDefaultType, 
-                      String attDefaultValue, DatatypeValidator dv, boolean isList){
-        int attrDeclIndex = createAttributeDecl();
-        fTempAttributeDecl.name.setValues(attQName);
-        fTempAttributeDecl.datatypeValidator = dv;
-        fTempAttributeDecl.type = attType;
-        fTempAttributeDecl.defaultType = attDefaultType;
-        fTempAttributeDecl.defaultValue = attDefaultValue;
-        fTempAttributeDecl.list = isList;
-        fTempAttributeDecl.enumeration = enumeration;
-
-        super.setAttributeDecl(templateElementIndex, attrDeclIndex, fTempAttributeDecl);
-    }
-
-    public int getAttributeDeclIndex(int elementIndex, QName attribute) {
-        if (elementIndex == -1) {
-            return -1;
-        }
-        int attDefIndex = getFirstAttributeDeclIndex(elementIndex);
-        while (attDefIndex != -1) {
-            getAttributeDecl(attDefIndex, fTempAttributeDecl);
-
-            if (fTempAttributeDecl.name.localpart == attribute.localpart &&
-                fTempAttributeDecl.name.uri == attribute.uri ) {
-                return attDefIndex;
-            }
-            attDefIndex = getNextAttributeDeclIndex(attDefIndex);
-        }
-        return -1;
-    } // getAttributeDeclIndex (int,QName)
-
-    /**
-     *@return the new contentSpec Index
-     */
-    protected int addContentSpecNode(int contentSpecType, int value, int otherValue, boolean mustBeUnique) {
-        fTempContentSpecNode.type = contentSpecType;
-        fTempContentSpecNode.value = value;
-        fTempContentSpecNode.otherValue = otherValue;
-        
-        int contentSpecIndex = createContentSpec();
-        setContentSpec(contentSpecIndex, fTempContentSpecNode);
-        return contentSpecIndex;
-    }
-                                                
-
-    //
-    // Private methods
-    //
-
-    // ensure capacity
-
-    private boolean ensureElementDeclCapacity(int chunk) {
-        try {
-            return  fScopeDefinedByElement[chunk][0] == -2;
-        } 
-        catch (ArrayIndexOutOfBoundsException ex) {
-             fScopeDefinedByElement= resize(fScopeDefinedByElement, fScopeDefinedByElement.length * 2);
-             fFromAnotherSchemaURI = resize(fFromAnotherSchemaURI, fFromAnotherSchemaURI.length *2);
-             fComplexTypeInfo =      resize(fComplexTypeInfo, fComplexTypeInfo.length *2);
-             fElementDeclDefaultType = resize(fElementDeclDefaultType,fElementDeclDefaultType.length*2);
-             fElementDeclDefaultValue = resize(fElementDeclDefaultValue,fElementDeclDefaultValue.length*2);
-             fElementDeclBlockSet = resize(fElementDeclBlockSet,fElementDeclBlockSet.length*2);
-             fElementDeclFinalSet = resize(fElementDeclFinalSet,fElementDeclFinalSet.length*2);
-             fElementDeclMiscFlags = resize(fElementDeclMiscFlags,fElementDeclMiscFlags.length*2);
-             fElementDeclEquivClassFullName = resize(fElementDeclEquivClassFullName,fElementDeclEquivClassFullName.length*2);
-        }
-        catch (NullPointerException ex) {
-            // ignore
-        }
-        fScopeDefinedByElement[chunk] = new int[CHUNK_SIZE];
-        for (int i=0; i<CHUNK_SIZE; i++) {
-            fScopeDefinedByElement[chunk][i] = -2;  //-1, 0 are all valid scope value.
-        }
-        fFromAnotherSchemaURI[chunk] = new String[CHUNK_SIZE];
-        fComplexTypeInfo[chunk] = new TraverseSchema.ComplexTypeInfo[CHUNK_SIZE];
-        fElementDeclDefaultType[chunk] = new int[CHUNK_SIZE];
-        fElementDeclDefaultValue[chunk] = new String[CHUNK_SIZE];
-        fElementDeclEquivClassFullName[chunk] = new String[CHUNK_SIZE];
-        fElementDeclBlockSet[chunk] = new int[CHUNK_SIZE]; // initialized to 0
-        fElementDeclFinalSet[chunk] = new int[CHUNK_SIZE]; // initialized to 0
-        fElementDeclMiscFlags[chunk] = new int[CHUNK_SIZE]; // initialized to 0
-        return true;
-    }
-
-
-    // resize initial chunk
-
-    private int[][] resize(int array[][], int newsize) {
-        int newarray[][] = new int[newsize][];
-        System.arraycopy(array, 0, newarray, 0, array.length);
-        return newarray;
-    }
-
-    private DatatypeValidator[][] resize(DatatypeValidator array[][], int newsize) {
-        // TODO
-        return array;
-    }
-
-    private XMLContentModel[][] resize(XMLContentModel array[][], int newsize) {
-        // TODO
-        return array;
-    }
-
-    private QName[][] resize(QName array[][], int newsize) {
-        // TODO
-        return array;
-    }
-
-    private String[][] resize(String array[][], int newsize) {
-        String newarray[][] = new String[newsize][];
-        System.arraycopy(array, 0, newarray, 0, array.length);
-        return newarray;
-    }
-    private TraverseSchema.ComplexTypeInfo[][] resize(TraverseSchema.ComplexTypeInfo array[][], int newsize) {
-        TraverseSchema.ComplexTypeInfo newarray[][] = new TraverseSchema.ComplexTypeInfo[newsize][];
-        System.arraycopy(array, 0, newarray, 0, array.length);
-        return newarray;
-    }
-
-} // class SchemaGrammar
diff --git a/src/org/apache/xerces/validators/schema/SchemaMessageProvider.java b/src/org/apache/xerces/validators/schema/SchemaMessageProvider.java
deleted file mode 100644
index 2aaa61d..0000000
--- a/src/org/apache/xerces/validators/schema/SchemaMessageProvider.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.schema;
-
-import org.apache.xerces.utils.XMLMessageProvider;
-import java.util.ResourceBundle;
-import java.util.ListResourceBundle;
-import java.util.Locale;
-
-/**
- * SchemaMessageProvider implements an XMLMessageProvider that
- * provides localizable error messages for the W3C XML Schema Language
- *
- */
-public class SchemaMessageProvider implements XMLMessageProvider {
-    /**
-     * The domain of messages concerning the XML Schema: Structures specification.
-     */
-    public static final String SCHEMA_DOMAIN = "http://www.w3.org/TR/xml-schema-1";
-
-    /**
-     *
-     */
-    public void setLocale(Locale locale) {
-        fLocale = locale;
-    }
-    /**
-     *
-     */
-    public Locale getLocale() {
-        return fLocale;
-    }
-
-    /**
-     * Creates a message from the specified key and replacement
-     * arguments, localized to the given locale.
-     *
-     * @param locale    The requested locale of the message to be
-     *                  created.
-     * @param key       The key for the message text.
-     * @param args      The arguments to be used as replacement text
-     *                  in the message created.
-     */
-    public String createMessage(Locale locale, int majorCode, int minorCode, Object args[]) {
-        boolean throwex = false;
-        if (fResourceBundle == null || locale != fLocale) {
-            if (locale != null)
-                fResourceBundle = ListResourceBundle.getBundle("org.apache.xerces.msg.SchemaMessages", locale);
-            if (fResourceBundle == null)
-                fResourceBundle = ListResourceBundle.getBundle("org.apache.xerces.msg.SchemaMessages");
-        }
-        if (majorCode < 0 || majorCode >= fgMessageKeys.length) {
-            majorCode = MSG_BAD_MAJORCODE;
-            throwex = true;
-        }
-        String msgKey = fgMessageKeys[majorCode];
-        String msg = fResourceBundle.getString(msgKey);
-        if (args != null) {
-            try {
-                msg = java.text.MessageFormat.format(msg, args);
-            } catch (Exception e) {
-                msg = fResourceBundle.getString(fgMessageKeys[MSG_FORMAT_FAILURE]);
-                msg += " " + fResourceBundle.getString(msgKey);
-            }
-        }
-
-        if (throwex) {
-            throw new RuntimeException(msg);
-        }
-        return msg;
-    }
-    //
-    //
-    //
-    private Locale fLocale = null;
-    private ResourceBundle fResourceBundle = null;
-    //
-    // Major codes
-    //
-    public static final int 
-        MSG_BAD_MAJORCODE = 0,              //  majorCode parameter to createMessage was out of bounds
-        MSG_FORMAT_FAILURE = 1,             //  exception thrown during messageFormat call
-        NoValidatorFor = 2,
-        IncorrectDatatype = 3,
-        AttMissingType = 4,
-        NotADatatype = 5,
-        TextOnlyContentWithType = 6,
-        FeatureUnsupported = 7,
-        NestedOnlyInElemOnly = 8,
-        EltRefOnlyInMixedElemOnly = 9,
-        OnlyInEltContent = 10,
-        OrderIsAll = 11,
-        DatatypeWithType = 12,
-        DatatypeQualUnsupported = 13,
-        GroupContentRestricted = 14,
-        UnknownBaseDatatype = 15,
-        OneOfTypeRefArchRef = 16,
-        NoContentForRef = 17,
-        IncorrectDefaultType = 18,
-        IllegalAttContent = 19,
-        ValueNotInteger = 20,
-        DatatypeError = 21,
-		TypeAlreadySet = 22,
-		GenericError = 23,
-		UnclassifiedError = 24,
-        // ...
-        MSG_MAX_CODE = 31;
-    //
-    // Minor Codes
-    //
-    public static final int
-        MSG_NONE = 0;
-
-    public static final String[] fgMessageKeys = {
-        "BadMajorCode",                 //   0, "The majorCode parameter to createMessage was out of bounds."
-        "FormatFailed",                 //   1, "An internal error occurred while formatting the following message:"
-        "NoValidatorFor",               //   2, "No validator for datatype {0}"
-        "IncorrectDatatype",            //   3, "Incorrect datatype: {0}" 
-        "AttMissingType",               //   4, "The {0} attribute must appear with a type attribute."
-        "NotADatatype",                 //   5, "{0} is not a datatype."
-        "TextOnlyContentWithType",      //   6, "The content attribute must be 'textOnly' if you specify a type attribute." 
-        "FeatureUnsupported",           //   7, "{0} is unsupported"
-        "NestedOnlyInElemOnly",         //   8, "Nested Element decls only allowed in elemOnly content"
-        "EltRefOnlyInMixedElemOnly",    //   9, "Element references only allowed in mixed or elemOnly content"
-        "OnlyInEltContent",             //  10, "{0} only allowed in elemOnly content."
-        "OrderIsAll",                   //  11, "{0} not allowed if the order is all."
-        "DatatypeWithType",             //  12, "Datatype qualifiers can only be used if you specify a type attribute."},
-        "DatatypeQualUnsupported",      //  13, "The datatype qualifier {0} is not supported."
-        "GroupContentRestricted",       //  14, "Error: {0} content must be one of element, group, modelGroupRef.  Saw {1}"
-        "UnknownBaseDatatype",          //  15, "Unknown base type {0} for type {1}." },
-        "OneOfTypeRefArchRef",          //  16, "Can only have one of type, ref, and archRef attributes."},
-        "NoContentForRef",              //  17, "Cannot have child content for an element declaration that has a ref attribute"
-        "IncorrectDefaultType",         //  18, "Incorrect type for {0}'s default value: {1}"
-        "IllegalAttContent",            //  19, "Illegal content {0} in attribute group"
-        "ValueNotInteger",              //  20, "Value of {0} is not an integer"
-        "DatatypeError",                //  21, "Datatype error {0}." 
-		"TypeAlreadySet",				//	22,	"The type of the element has already been declared."
-		"GenericError",					//	23, "Schema error: {0}."
-		"UnclassifiedError",			//	24,	"Unclassified error."
-    };
-}
diff --git a/src/org/apache/xerces/validators/schema/SchemaSymbols.java b/src/org/apache/xerces/validators/schema/SchemaSymbols.java
deleted file mode 100644
index b2bdca2..0000000
--- a/src/org/apache/xerces/validators/schema/SchemaSymbols.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.schema;
-
-
-/**
- *             Collection of symbols used to parse a Schema Grammar
- *             We have temporary references to this class from
- *             SchemaImporter but we will be moving all the
- *             SchemaImporter functionality to the Grammar classes
- * 
- * @author jeffrey rodriguez
- */
-public final  class SchemaSymbols {
-    public static final String URI_XSI =  "http://www.w3.org/1999/XMLSchema-instance";
-    public static final String URI_SCHEMAFORSCHEMA =  "http://www.w3.org/1999/XMLSchema";
-    public static final String XSI_SCHEMALOCACTION =  "schemaLocation";
-    public static final String XSI_NONAMESPACESCHEMALOCACTION =  "noNamespaceSchemaLocation";
-    public static final String XSI_TYPE =  "type";
-
-    public static final String ELT_ALL =  "all";
-    public static final String ELT_ANNOTATION =  "annotation";
-    public static final String ELT_ANY =  "any";
-    public static final String ELT_WILDCARD = "any";
-    public static final String ELT_ANYATTRIBUTE =  "anyAttribute";
-    public static final String ELT_ATTRIBUTE =  "attribute";
-    public static final String ELT_ATTRIBUTEGROUP =  "attributeGroup";
-    public static final String ELT_CHOICE =  "choice";
-    public static final String ELT_COMPLEXTYPE =  "complexType";
-    public static final String ELT_CONTENT =  "content";
-    public static final String ELT_DURATION =  "duration";
-    public static final String ELT_ELEMENT =  "element";
-    public static final String ELT_ENCODING =  "encoding";
-    public static final String ELT_ENUMERATION =  "enumeration";
-    public static final String ELT_GROUP =  "group";
-    public static final String ELT_IMPORT =  "import";
-    public static final String ELT_INCLUDE =  "include";
-    public static final String ELT_KEY =  "key";
-    public static final String ELT_KEYREF =  "keyref";
-    public static final String ELT_LENGTH =  "length";
-    public static final String ELT_MAXEXCLUSIVE =  "maxExclusive";
-    public static final String ELT_MAXINCLUSIVE =  "maxInclusive";
-    public static final String ELT_MAXLENGTH =  "maxLength";
-    public static final String ELT_MINEXCLUSIVE =  "minExclusive";
-    public static final String ELT_MININCLUSIVE =  "minInclusive";
-    public static final String ELT_MINLENGTH =  "minLength";
-    public static final String ELT_NOTATION =  "notation";
-    public static final String ELT_PATTERN =  "pattern";
-    public static final String ELT_PERIOD =  "period";
-    public static final String ELT_PRECISION =  "precision";
-    public static final String ELT_SCALE =  "scale";
-    public static final String ELT_SCHEMA =  "schema";
-    public static final String ELT_SELECTOR =  "selector";
-    public static final String ELT_SEQUENCE =  "sequence";
-    public static final String ELT_SIMPLETYPE =  "simpleType";
-    public static final String ELT_UNIQUE = "unique";
-    public static final String ATT_ABSTRACT =  "abstract";
-    public static final String ATT_ATTRIBUTEFORMDEFAULT =  "attributeFormDefault";
-    public static final String ATT_BASE =  "base";
-    public static final String ATT_BLOCK =  "block";
-    public static final String ATT_BLOCKDEFAULT =  "blockDefault";
-    public static final String ATT_CONTENT  = "content";
-    public static final String ATT_DEFAULT =  "default";
-    public static final String ATT_DERIVEDBY = "derivedBy";
-    public static final String ATT_ELEMENTFORMDEFAULT =  "elementFormDefault";
-    public static final String ATT_EQUIVCLASS =  "equivClass";
-    public static final String ATT_FINAL =  "final";
-    public static final String ATT_FINALDEFAULT =  "finalDefault";
-    public static final String ATT_FIXED =  "fixed";
-    public static final String ATT_FORM =  "form";
-    public static final String ATT_MAXOCCURS =  "maxOccurs";
-    public static final String ATT_MINOCCURS =  "minOccurs";
-    public static final String ATT_NAME =  "name";
-    public static final String ATT_NAMESPACE =  "namespace";
-    public static final String ATT_NULLABLE =  "nullable";
-    public static final String ATT_PROCESSCONTENTS =  "processContents";
-    public static final String ATT_REF =  "ref";
-    public static final String ATT_REFER =  "refer";
-    public static final String ATT_SCHEMALOCATION =  "schemaLocation";
-    public static final String ATT_SYSTEM =  "system";
-    public static final String ATT_TARGETNAMESPACE =  "targetNamespace";
-    public static final String ATT_TYPE =  "type";
-    public static final String ATT_USE =  "use";
-    public static final String ATT_VALUE = "value";
-    public static final String ATTVAL_TWOPOUNDANY =  "##any";
-    public static final String ATTVAL_TWOPOUNDLOCAL =  "##local";
-    public static final String ATTVAL_TWOPOUNDOTHER =  "##other";
-    public static final String ATTVAL_POUNDALL =  "#all";
-    public static final String ATTVAL_BASE64 =  "base64";
-    public static final String ATTVAL_BOOLEAN =  "boolean";
-    public static final String ATTVAL_DEFAULT =  "default";
-    public static final String ATTVAL_ELEMENTONLY =  "elementOnly";
-    public static final String ATTVAL_EMPTY =  "empty";
-    public static final String ATTVAL_EXTENSION =  "extension";
-    public static final String ATTVAL_FALSE =  "false";
-    public static final String ATTVAL_FIXED =  "fixed";
-    public static final String ATTVAL_HEX =  "hex";
-    public static final String ATTVAL_ID =  "ID";
-    public static final String ATTVAL_LAX =  "lax";
-    public static final String ATTVAL_LIST =  "list";
-    public static final String ATTVAL_MAXLENGTH =  "maxLength";
-    public static final String ATTVAL_MINLENGTH =  "minLength";
-    public static final String ATTVAL_MIXED =  "mixed";
-    public static final String ATTVAL_NCNAME =  "NCName";
-    public static final String ATTVAL_OPTIONAL =  "optional";
-    public static final String ATTVAL_PROHIBITED =  "prohibited";
-    public static final String ATTVAL_QNAME =  "QName";
-    public static final String ATTVAL_QUALIFIED =  "qualified";
-    public static final String ATTVAL_REQUIRED =  "required";
-    public static final String ATTVAL_RESTRICTION =  "restriction";
-    public static final String ATTVAL_SKIP =  "skip";
-    public static final String ATTVAL_STRING =  "string";
-    public static final String ATTVAL_TEXTONLY =  "textOnly";
-    public static final String ATTVAL_TIMEDURATION =  "timeDuration";
-    public static final String ATTVAL_TRUE =  "true";
-    public static final String ATTVAL_UNQUALIFIED =  "unqualified";
-    public static final String ATTVAL_URI =  "uri";
-    public static final String ATTVAL_URIREFERENCE =  "uriReference";
-    public static final String ATTVAL_EQUIVCLASS = "equivclass";
-
-
-    public static final int                     EMPTY_SET = 0;          
-    public static final int                     EXTENSION = 1;
-    public static final int                     RESTRICTION = 2;
-    public static final int                     REPRODUCTION = 4;
-    public static final int                     LIST = 8;
-    public static final int                     ENUMERATION = 16;
-    public static final int                     EQUIVCLASS = 32;
-
-    public static final int                     CHOICE = 0;                     // group orders
-    public static final int                     SEQUENCE = 1;           // group orders
-    public static final int                     ALL = 2;                        // group orders
-
-    public static final int                     INFINITY = -1;          // used for maxOccurs
-
-    public static final int NULLABLE = 1;
-    public static final int ABSTRACT = 2;
-
-}
diff --git a/src/org/apache/xerces/validators/schema/TraverseSchema.java b/src/org/apache/xerces/validators/schema/TraverseSchema.java
deleted file mode 100644
index aa4116c..0000000
--- a/src/org/apache/xerces/validators/schema/TraverseSchema.java
+++ /dev/null
@@ -1,4531 +0,0 @@
-
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.xerces.validators.schema;
-
-import  org.apache.xerces.framework.XMLErrorReporter;
-import  org.apache.xerces.validators.common.Grammar;
-import  org.apache.xerces.validators.common.GrammarResolver;
-import  org.apache.xerces.validators.common.GrammarResolverImpl;
-import  org.apache.xerces.validators.common.XMLElementDecl;
-import  org.apache.xerces.validators.common.XMLAttributeDecl;
-import  org.apache.xerces.validators.schema.SchemaSymbols;
-import  org.apache.xerces.validators.schema.XUtil;
-import  org.apache.xerces.validators.datatype.DatatypeValidator;
-import  org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
-import  org.apache.xerces.validators.datatype.InvalidDatatypeValueException;
-import  org.apache.xerces.utils.StringPool;
-import  org.w3c.dom.Element;
-
-//REVISIT: for now, import everything in the DOM package
-import  org.w3c.dom.*;
-import java.util.*;
-import java.net.URL;
-import java.net.MalformedURLException;
-
-//Unit Test 
-import  org.apache.xerces.parsers.DOMParser;
-import  org.apache.xerces.validators.common.XMLValidator;
-import  org.apache.xerces.validators.datatype.DatatypeValidator.*;
-import  org.apache.xerces.validators.datatype.InvalidDatatypeValueException;
-import  org.apache.xerces.framework.XMLContentSpec;
-import  org.apache.xerces.utils.QName;
-import  org.apache.xerces.utils.NamespacesScope;
-import  org.apache.xerces.parsers.SAXParser;
-import  org.apache.xerces.framework.XMLParser;
-import  org.apache.xerces.framework.XMLDocumentScanner;
-
-import  org.xml.sax.InputSource;
-import  org.xml.sax.SAXParseException;
-import  org.xml.sax.EntityResolver;
-import  org.xml.sax.ErrorHandler;
-import  org.xml.sax.SAXException;
-import  java.io.IOException;
-import  org.w3c.dom.Document;
-import  org.apache.xml.serialize.OutputFormat;
-import  org.apache.xml.serialize.XMLSerializer;
-import  org.apache.xerces.validators.schema.SchemaSymbols;
-
-
-
-
-/**
- * Instances of this class get delegated to Traverse the Schema and
- * to populate the Grammar internal representation by
- * instances of Grammar objects.
- * Traverse a Schema Grammar:
-     * As of April 07, 2000 the following is the
-     * XML Representation of Schemas and Schema components,
-     * Chapter 4 of W3C Working Draft.
-     * <schema 
-     *   attributeFormDefault = qualified | unqualified 
-     *   blockDefault = #all or (possibly empty) subset of {equivClass, extension, restriction} 
-     *   elementFormDefault = qualified | unqualified 
-     *   finalDefault = #all or (possibly empty) subset of {extension, restriction} 
-     *   id = ID 
-     *   targetNamespace = uriReference 
-     *   version = string>
-     *   Content: ((include | import | annotation)* , ((simpleType | complexType | element | group | attribute | attributeGroup | notation) , annotation*)+)
-     * </schema>
-     * 
-     * 
-     * <attribute 
-     *   form = qualified | unqualified 
-     *   id = ID 
-     *   name = NCName 
-     *   ref = QName 
-     *   type = QName 
-     *   use = default | fixed | optional | prohibited | required 
-     *   value = string>
-     *   Content: (annotation? , simpleType?)
-     * </>
-     * 
-     * <element 
-     *   abstract = boolean 
-     *   block = #all or (possibly empty) subset of {equivClass, extension, restriction} 
-     *   default = string 
-     *   equivClass = QName 
-     *   final = #all or (possibly empty) subset of {extension, restriction} 
-     *   fixed = string 
-     *   form = qualified | unqualified 
-     *   id = ID 
-     *   maxOccurs = string 
-     *   minOccurs = nonNegativeInteger 
-     *   name = NCName 
-     *   nullable = boolean 
-     *   ref = QName 
-     *   type = QName>
-     *   Content: (annotation? , (simpleType | complexType)? , (unique | key | keyref)*)
-     * </>
-     * 
-     * 
-     * <complexType 
-     *   abstract = boolean 
-     *   base = QName 
-     *   block = #all or (possibly empty) subset of {extension, restriction} 
-     *   content = elementOnly | empty | mixed | textOnly 
-     *   derivedBy = extension | restriction 
-     *   final = #all or (possibly empty) subset of {extension, restriction} 
-     *   id = ID 
-     *   name = NCName>
-     *   Content: (annotation? , (((minExclusive | minInclusive | maxExclusive | maxInclusive | precision | scale | length | minLength | maxLength | encoding | period | duration | enumeration | pattern)* | (element | group | all | choice | sequence | any)*) , ((attribute | attributeGroup)* , anyAttribute?)))
-     * </>
-     * 
-     * 
-     * <attributeGroup 
-     *   id = ID 
-     *   name = NCName
-     *   ref = QName>
-     *   Content: (annotation?, (attribute|attributeGroup), anyAttribute?)
-     * </>
-     * 
-     * <anyAttribute 
-     *   id = ID 
-     *   namespace = ##any | ##other | ##local | list of {uri, ##targetNamespace}>
-     *   Content: (annotation?)
-     * </anyAttribute>
-     * 
-     * <group 
-     *   id = ID 
-     *   maxOccurs = string 
-     *   minOccurs = nonNegativeInteger 
-     *   name = NCName 
-     *   ref = QName>
-     *   Content: (annotation? , (element | group | all | choice | sequence | any)*)
-     * </>
-     * 
-     * <all 
-     *   id = ID 
-     *   maxOccurs = string 
-     *   minOccurs = nonNegativeInteger>
-     *   Content: (annotation? , (element | group | choice | sequence | any)*)
-     * </all>
-     * 
-     * <choice 
-     *   id = ID 
-     *   maxOccurs = string 
-     *   minOccurs = nonNegativeInteger>
-     *   Content: (annotation? , (element | group | choice | sequence | any)*)
-     * </choice>
-     * 
-     * <sequence 
-     *   id = ID 
-     *   maxOccurs = string 
-     *   minOccurs = nonNegativeInteger>
-     *   Content: (annotation? , (element | group | choice | sequence | any)*)
-     * </sequence>
-     * 
-     * 
-     * <any 
-     *   id = ID 
-     *   maxOccurs = string 
-     *   minOccurs = nonNegativeInteger 
-     *   namespace = ##any | ##other | ##local | list of {uri, ##targetNamespace} 
-     *   processContents = lax | skip | strict>
-     *   Content: (annotation?)
-     * </any>
-     * 
-     * <unique 
-     *   id = ID 
-     *   name = NCName>
-     *   Content: (annotation? , (selector , field+))
-     * </unique>
-     * 
-     * <key 
-     *   id = ID 
-     *   name = NCName>
-     *   Content: (annotation? , (selector , field+))
-     * </key>
-     * 
-     * <keyref 
-     *   id = ID 
-     *   name = NCName 
-     *   refer = QName>
-     *   Content: (annotation? , (selector , field+))
-     * </keyref>
-     * 
-     * <selector>
-     *   Content: XPathExprApprox : An XPath expression 
-     * </selector>
-     * 
-     * <field>
-     *   Content: XPathExprApprox : An XPath expression 
-     * </field>
-     * 
-     * 
-     * <notation 
-     *   id = ID 
-     *   name = NCName 
-     *   public = A public identifier, per ISO 8879 
-     *   system = uriReference>
-     *   Content: (annotation?)
-     * </notation>
-     * 
-     * <annotation>
-     *   Content: (appinfo | documentation)*
-     * </annotation>
-     * 
-     * <include 
-     *   id = ID 
-     *   schemaLocation = uriReference>
-     *   Content: (annotation?)
-     * </include>
-     * 
-     * <import 
-     *   id = ID 
-     *   namespace = uriReference 
-     *   schemaLocation = uriReference>
-     *   Content: (annotation?)
-     * </import>
-     * 
-     * <simpleType
-     *   abstract = boolean 
-     *   base = QName 
-     *   derivedBy = | list | restriction  : restriction
-     *   id = ID 
-     *   name = NCName>
-     *   Content: ( annotation? , ( minExclusive | minInclusive | maxExclusive | maxInclusive | precision | scale | length | minLength | maxLength | encoding | period | duration | enumeration | pattern )* )
-     * </simpleType>
-     * 
-     * <length
-     *   id = ID 
-     *   value = nonNegativeInteger>
-     *   Content: ( annotation? )
-     * </length>
-     * 
-     * <minLength
-     *   id = ID 
-     *   value = nonNegativeInteger>
-     *   Content: ( annotation? )
-     * </minLength>
-     * 
-     * <maxLength
-     *   id = ID 
-     *   value = nonNegativeInteger>
-     *   Content: ( annotation? )
-     * </maxLength>
-     * 
-     * 
-     * <pattern
-     *   id = ID 
-     *   value = string>
-     *   Content: ( annotation? )
-     * </pattern>
-     * 
-     * 
-     * <enumeration
-     *   id = ID 
-     *   value = string>
-     *   Content: ( annotation? )
-     * </enumeration>
-     * 
-     * <maxInclusive
-     *   id = ID 
-     *   value = string>
-     *   Content: ( annotation? )
-     * </maxInclusive>
-     * 
-     * <maxExclusive
-     *   id = ID 
-     *   value = string>
-     *   Content: ( annotation? )
-     * </maxExclusive>
-     * 
-     * <minInclusive
-     *   id = ID 
-     *   value = string>
-     *   Content: ( annotation? )
-     * </minInclusive>
-     * 
-     * 
-     * <minExclusive
-     *   id = ID 
-     *   value = string>
-     *   Content: ( annotation? )
-     * </minExclusive>
-     * 
-     * <precision
-     *   id = ID 
-     *   value = nonNegativeInteger>
-     *   Content: ( annotation? )
-     * </precision>
-     * 
-     * <scale
-     *   id = ID 
-     *   value = nonNegativeInteger>
-     *   Content: ( annotation? )
-     * </scale>
-     * 
-     * <encoding
-     *   id = ID 
-     *   value = | hex | base64 >
-     *   Content: ( annotation? )
-     * </encoding>
-     * 
-     * 
-     * <duration
-     *   id = ID 
-     *   value = timeDuration>
-     *   Content: ( annotation? )
-     * </duration>
-     * 
-     * <period
-     *   id = ID 
-     *   value = timeDuration>
-     *   Content: ( annotation? )
-     * </period>
-     * 
- * 
- * @author Eric Ye, Jeffrey Rodriguez, Andy Clark
- *  
- * @see                  org.apache.xerces.validators.common.Grammar
- *
- * @version $Id$
- */
-
-public class TraverseSchema implements 
-                            NamespacesScope.NamespacesHandler{
-
-    
-    //CONSTANTS
-    private static final int TOP_LEVEL_SCOPE = -1;
-
-    //debuggin
-    private static boolean DEBUGGING = false;
-
-    //private data members
-
-
-    private XMLErrorReporter    fErrorReporter = null;
-    private StringPool          fStringPool    = null;
-
-    private GrammarResolver fGrammarResolver = null;
-    private SchemaGrammar fSchemaGrammar = null;
-
-    private Element fSchemaRootElement;
-
-    private DatatypeValidatorFactoryImpl fDatatypeRegistry =  
-                          DatatypeValidatorFactoryImpl.getDatatypeRegistry();
-
-    private Hashtable fComplexTypeRegistry = new Hashtable();
-    private Hashtable fAttributeDeclRegistry = new Hashtable();
-
-    private Vector fIncludeLocations = new Vector();
-    private Vector fImportLocations = new Vector();
-
-
-    private int fAnonTypeCount =0;
-    private int fScopeCount=0;
-    private int fCurrentScope=TOP_LEVEL_SCOPE;
-    private int fSimpleTypeAnonCount = 0;
-    private Stack fCurrentTypeNameStack = new Stack();
-    private Hashtable fElementRecurseComplex = new Hashtable();
-
-    private boolean fElementDefaultQualified = false;
-    private boolean fAttributeDefaultQualified = false;
-
-    private int fTargetNSURI;
-    private String fTargetNSURIString = "";
-    private NamespacesScope fNamespacesScope = null;
-    private String fCurrentSchemaURL = "";
-
-    private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
-    private XMLElementDecl fTempElementDecl = new XMLElementDecl();
-
-    // REVISIT: maybe need to be moved into SchemaGrammar class
-    public class ComplexTypeInfo {
-        public String typeName;
-        
-        public DatatypeValidator baseDataTypeValidator;
-        public ComplexTypeInfo baseComplexTypeInfo;
-
-        public int derivedBy = 0;
-        public int blockSet = 0;
-        public int finalSet = 0;
-
-        public boolean isAbstract = false;
-
-        public int scopeDefined = -1;
-
-        public int contentType;
-        public int contentSpecHandle = -1;
-        public int templateElementIndex = -1;
-        public int attlistHead = -1;
-        public DatatypeValidator datatypeValidator;
-    }
-
-
-    //REVISIT: verify the URI.
-    public final static String SchemaForSchemaURI = "http://www.w3.org/TR-1/Schema";
-
-    private TraverseSchema( ) {
-        // new TraverseSchema() is forbidden;
-    }
-
-
-    public void setGrammarResolver(GrammarResolver grammarResolver){
-        fGrammarResolver = grammarResolver;
-    }
-    public void startNamespaceDeclScope(int prefix, int uri){
-        //TO DO
-    }
-    public void endNamespaceDeclScope(int prefix){
-        //TO DO, do we need to do anything here?
-    }
-
-    
-
-    private String resolvePrefixToURI (String prefix) throws Exception  {
-        String uriStr = fStringPool.toString(fNamespacesScope.getNamespaceForPrefix(fStringPool.addSymbol(prefix)));
-        if (uriStr == null) {
-            // REVISIT: Localize
-            reportGenericSchemaError("prefix : [" + prefix +"] can not be resolved to a URI");
-            return "";
-        }
-
-        //REVISIT, !!!! a hack: needs to be updated later, cause now we only use localpart to key build-in datatype.
-        if ( prefix.length()==0 && uriStr.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) 
-             && fTargetNSURIString.length() == 0) {
-            uriStr = "";
-        }
-
-        return uriStr;
-    }
-
-    public  TraverseSchema(Element root, StringPool stringPool, 
-                           SchemaGrammar schemaGrammar, 
-                           GrammarResolver grammarResolver,
-                           XMLErrorReporter errorReporter,
-                           String schemaURL
-                           ) throws Exception {
-        fErrorReporter = errorReporter;
-        fCurrentSchemaURL = schemaURL;
-        doTraverseSchema(root, stringPool, schemaGrammar, grammarResolver);
-    }
-
-    public  TraverseSchema(Element root, StringPool stringPool, 
-                           SchemaGrammar schemaGrammar, 
-                           GrammarResolver grammarResolver
-                           ) throws Exception {
-        doTraverseSchema(root, stringPool, schemaGrammar, grammarResolver);
-    }
-
-    public  void doTraverseSchema(Element root, StringPool stringPool, 
-                           SchemaGrammar schemaGrammar, 
-                           GrammarResolver grammarResolver) throws Exception {
-
-        fNamespacesScope = new NamespacesScope(this);
-        
-        fSchemaRootElement = root;
-        fStringPool = stringPool;
-        fSchemaGrammar = schemaGrammar;
-        fGrammarResolver = grammarResolver;
-
-        if (root == null) { 
-            // REVISIT: Anything to do?
-            return;
-        }
-
-        //Make sure namespace binding is defaulted
-        String rootPrefix = root.getPrefix();
-        if( rootPrefix == null || rootPrefix.length() == 0 ){
-            String xmlns = root.getAttribute("xmlns");
-            if( xmlns.length() == 0 )
-                root.setAttribute("xmlns", SchemaSymbols.URI_SCHEMAFORSCHEMA );
-        }
-
-        //Retrieve the targetnamespace URI information
-        fTargetNSURIString = root.getAttribute(SchemaSymbols.ATT_TARGETNAMESPACE);
-        if (fTargetNSURIString==null) {
-            fTargetNSURIString="";
-        }
-        fTargetNSURI = fStringPool.addSymbol(fTargetNSURIString);
-
-        if (fGrammarResolver == null) {
-            // REVISIT: Localize
-            reportGenericSchemaError("Internal error: don't have a GrammarResolver for TraverseSchema");
-        }
-        else{
-            fSchemaGrammar.setComplexTypeRegistry(fComplexTypeRegistry);
-            fSchemaGrammar.setDatatypeRegistry(fDatatypeRegistry);
-            fSchemaGrammar.setAttributeDeclRegistry(fAttributeDeclRegistry);
-            fSchemaGrammar.setNamespacesScope(fNamespacesScope);
-            fSchemaGrammar.setTargetNamespaceURI(fTargetNSURIString);
-            fGrammarResolver.putGrammar(fTargetNSURIString, fSchemaGrammar);
-        }
-        
-
-
-        // Retrived the Namespace mapping from the schema element.
-        NamedNodeMap schemaEltAttrs = root.getAttributes();
-        int i = 0;
-        Attr sattr = null;
-
-        boolean seenXMLNS = false;                                        
-        while ((sattr = (Attr)schemaEltAttrs.item(i++)) != null) {
-            String attName = sattr.getName();
-            if (attName.startsWith("xmlns:")) {
-                String attValue = sattr.getValue();
-                String prefix = attName.substring(attName.indexOf(":")+1);
-                fNamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(prefix),
-                                                        fStringPool.addSymbol(attValue) );
-            }
-            if (attName.equals("xmlns")) {
-
-                String attValue = sattr.getValue();
-                fNamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(""),
-                                                        fStringPool.addSymbol(attValue) );
-                seenXMLNS = true;
-            }
-
-        }
-        if (!seenXMLNS && fTargetNSURIString.length() == 0 ) {
-            fNamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(""),
-                                                    fStringPool.addSymbol("") );
-        }
-
-        fElementDefaultQualified = 
-            root.getAttribute(SchemaSymbols.ATT_ELEMENTFORMDEFAULT).equals(SchemaSymbols.ATTVAL_QUALIFIED);
-        fAttributeDefaultQualified = 
-            root.getAttribute(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT).equals(SchemaSymbols.ATTVAL_QUALIFIED);
-        
-        //REVISIT, really sticky when noTargetNamesapce, for now, we assume everyting is in the same name space);
-        if (fTargetNSURI == StringPool.EMPTY_STRING) {
-            fElementDefaultQualified = true;
-            //fAttributeDefaultQualified = true;
-        }
-
-
-        //fScopeCount++;
-        fCurrentScope = -1;
-
-
-        checkTopLevelDuplicateNames(root);
-
-        //extract all top-level attribute, attributeGroup, and group Decls and put them in the 3 hasn table in the SchemaGrammar.
-        extractTopLevel3Components(root);
-
-        for (Element child = XUtil.getFirstChildElement(root); child != null;
-            child = XUtil.getNextSiblingElement(child)) {
-
-            String name = child.getNodeName();
-
-            if (name.equals(SchemaSymbols.ELT_ANNOTATION) ) {
-                traverseAnnotationDecl(child);
-            } else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE )) {
-                traverseSimpleTypeDecl(child);
-            } else if (name.equals(SchemaSymbols.ELT_COMPLEXTYPE )) {
-                traverseComplexTypeDecl(child);
-            } else if (name.equals(SchemaSymbols.ELT_ELEMENT )) { 
-                traverseElementDecl(child);
-            } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
-                //traverseAttributeGroupDecl(child);
-            } else if (name.equals( SchemaSymbols.ELT_ATTRIBUTE ) ) {
-                traverseAttributeDecl( child, null );
-            } else if (name.equals( SchemaSymbols.ELT_WILDCARD) ) {
-                traverseWildcardDecl( child);
-            } else if (name.equals(SchemaSymbols.ELT_GROUP) && child.getAttribute(SchemaSymbols.ATT_REF).equals("")) {
-                //traverseGroupDecl(child);
-            } else if (name.equals(SchemaSymbols.ELT_NOTATION)) {
-                ; //TO DO
-            }
-            else if (name.equals(SchemaSymbols.ELT_INCLUDE)) {
-                traverseInclude(child); 
-            }
-            else if (name.equals(SchemaSymbols.ELT_IMPORT)) {
-                traverseImport(child); 
-            }
-        } // for each child node
-
-    } // traverseSchema(Element)
-
-    private void checkTopLevelDuplicateNames(Element root) {
-        //TO DO : !!!
-    }
-
-    private void extractTopLevel3Components(Element root){
-        
-        for (Element child = XUtil.getFirstChildElement(root); child != null;
-            child = XUtil.getNextSiblingElement(child)) {
-
-            String name = child.getNodeName();
-
-            if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
-                fSchemaGrammar.topLevelAttrGrpDecls.put(name, child);
-            } else if (name.equals( SchemaSymbols.ELT_ATTRIBUTE ) ) {
-                fSchemaGrammar.topLevelAttrDecls.put(name, child);
-            } else if (name.equals(SchemaSymbols.ELT_GROUP) && child.getAttribute(SchemaSymbols.ATT_REF).equals("")) {
-                fSchemaGrammar.topLevelGroupDecls.put(name, child);
-            } 
-        } // for each child node
-    }
-
-    /**
-     * Expands a system id and returns the system id as a URL, if
-     * it can be expanded. A return value of null means that the
-     * identifier is already expanded. An exception thrown
-     * indicates a failure to expand the id.
-     *
-     * @param systemId The systemId to be expanded.
-     *
-     * @return Returns the URL object representing the expanded system
-     *         identifier. A null value indicates that the given
-     *         system identifier is already expanded.
-     *
-     */
-    private String expandSystemId(String systemId, String currentSystemId) throws Exception{
-     String id = systemId;
-
-     // check for bad parameters id
-     if (id == null || id.length() == 0) {
-         return systemId;
-     }
-
-     // if id already expanded, return
-     try {
-         URL url = new URL(id);
-         if (url != null) {
-             return systemId;
-         }
-     }
-     catch (MalformedURLException e) {
-         // continue on...
-     }
-
-     // normalize id
-     id = fixURI(id);
-
-     // normalize base
-     URL base = null;
-     URL url = null;
-     try {
-         if (currentSystemId == null) {
-             String dir;
-             try {
-                 dir = fixURI(System.getProperty("user.dir"));
-             }
-             catch (SecurityException se) {
-                 dir = "";
-             }
-             if (!dir.endsWith("/")) {
-                 dir = dir + "/";
-             }
-             base = new URL("file", "", dir);
-         }
-         else {
-             base = new URL(currentSystemId);
-         }
-
-         // expand id
-         url = new URL(base, id);
-     }
-     catch (Exception e) {
-         // let it go through
-     }
-     if (url == null) {
-         return systemId;
-     }
-     return url.toString();
-    }
-    /**
-     * Fixes a platform dependent filename to standard URI form.
-     *
-     * @param str The string to fix.
-     *
-     * @return Returns the fixed URI string.
-     */
-    private static String fixURI(String str) {
-
-        // handle platform dependent strings
-        str = str.replace(java.io.File.separatorChar, '/');
-
-        // Windows fix
-        if (str.length() >= 2) {
-            char ch1 = str.charAt(1);
-            if (ch1 == ':') {
-                char ch0 = Character.toUpperCase(str.charAt(0));
-                if (ch0 >= 'A' && ch0 <= 'Z') {
-                    str = "/" + str;
-                }
-            }
-        }
-
-        // done
-        return str;
-    }
-
-
-    private void traverseInclude(Element includeDecl) throws Exception {
-
-        //TO DO: !!!!! location needs to be resolved first.
-
-        String location = includeDecl.getAttribute(SchemaSymbols.ATT_SCHEMALOCATION);
-        location = expandSystemId(location, fCurrentSchemaURL);
-
-        if (fIncludeLocations.contains((Object)location)) {
-            return;
-        }
-        fIncludeLocations.addElement((Object)location);
-
-        DOMParser parser = new DOMParser() {
-            public void ignorableWhitespace(char ch[], int start, int length) {}
-            public void ignorableWhitespace(int dataIdx) {}
-        };
-        parser.setEntityResolver( new Resolver() );
-        parser.setErrorHandler(  new ErrorHandler() );
-
-        try {
-            parser.setFeature("http://xml.org/sax/features/validation", false);
-            parser.setFeature("http://xml.org/sax/features/namespaces", true);
-            parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
-        }catch(  org.xml.sax.SAXNotRecognizedException e ) {
-            e.printStackTrace();
-        }catch( org.xml.sax.SAXNotSupportedException e ) {
-            e.printStackTrace();
-        }
-
-        try {
-            parser.parse( location);
-        }catch( IOException e ) {
-            e.printStackTrace();
-        }catch( SAXException e ) {
-            //e.printStackTrace();
-        }
-
-        Document     document   = parser.getDocument(); //Our Grammar
-        Element root = null;
-        if (document != null) {
-            root = document.getDocumentElement();
-        }
-
-        if (root != null) {
-            String targetNSURI = root.getAttribute(SchemaSymbols.ATT_TARGETNAMESPACE);
-            if (targetNSURI.length() > 0 && !targetNSURI.equals(fTargetNSURIString) ) {
-                // REVISIT: Localize
-                reportGenericSchemaError("included schema '"+location+"' has a different targetNameSpace '"
-                                         +targetNSURI+"'");
-            }
-            else {
-                boolean saveElementDefaultQualified = fElementDefaultQualified;
-                boolean saveAttributeDefaultQualified = fAttributeDefaultQualified;
-                int saveScope = fCurrentScope;
-                String savedSchemaURL = fCurrentSchemaURL;
-                Element saveRoot = fSchemaRootElement;
-                fSchemaRootElement = root;
-                fCurrentSchemaURL = location;
-                traverseIncludedSchema(root);
-                fCurrentSchemaURL = savedSchemaURL;
-                fCurrentScope = saveScope;
-                fElementDefaultQualified = saveElementDefaultQualified;
-                fAttributeDefaultQualified = saveAttributeDefaultQualified;
-                fSchemaRootElement = saveRoot;
-            }
-
-        }
-
-    }
-
-    private void traverseIncludedSchema(Element root) throws Exception {
-        // Retrived the Namespace mapping from the schema element.
-        NamedNodeMap schemaEltAttrs = root.getAttributes();
-        int i = 0;
-        Attr sattr = null;
-
-        boolean seenXMLNS = false;                                        
-        while ((sattr = (Attr)schemaEltAttrs.item(i++)) != null) {
-            String attName = sattr.getName();
-            if (attName.startsWith("xmlns:")) {
-                String attValue = sattr.getValue();
-                String prefix = attName.substring(attName.indexOf(":")+1);
-                fNamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(prefix),
-                                                        fStringPool.addSymbol(attValue) );
-            }
-            if (attName.equals("xmlns")) {
-
-                String attValue = sattr.getValue();
-                fNamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(""),
-                                                        fStringPool.addSymbol(attValue) );
-                seenXMLNS = true;
-            }
-
-        }
-        if (!seenXMLNS && fTargetNSURIString.length() == 0 ) {
-            fNamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(""),
-                                                    fStringPool.addSymbol("") );
-        }
-
-        fElementDefaultQualified = 
-            root.getAttribute(SchemaSymbols.ATT_ELEMENTFORMDEFAULT).equals(SchemaSymbols.ATTVAL_QUALIFIED);
-        fAttributeDefaultQualified = 
-            root.getAttribute(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT).equals(SchemaSymbols.ATTVAL_QUALIFIED);
-        
-        //REVISIT, really sticky when noTargetNamesapce, for now, we assume everyting is in the same name space);
-        if (fTargetNSURI == StringPool.EMPTY_STRING) {
-            fElementDefaultQualified = true;
-            //fAttributeDefaultQualified = true;
-        }
-
-        //fScopeCount++;
-        fCurrentScope = -1;
-
-
-        checkTopLevelDuplicateNames(root);
-
-        //extract all top-level attribute, attributeGroup, and group Decls and put them in the 3 hasn table in the SchemaGrammar.
-        extractTopLevel3Components(root);
-
-        for (Element child = XUtil.getFirstChildElement(root); child != null;
-            child = XUtil.getNextSiblingElement(child)) {
-
-            String name = child.getNodeName();
-
-            if (name.equals(SchemaSymbols.ELT_ANNOTATION) ) {
-                traverseAnnotationDecl(child);
-            } else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE )) {
-                traverseSimpleTypeDecl(child);
-            } else if (name.equals(SchemaSymbols.ELT_COMPLEXTYPE )) {
-                traverseComplexTypeDecl(child);
-            } else if (name.equals(SchemaSymbols.ELT_ELEMENT )) { 
-                traverseElementDecl(child);
-            } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
-                //traverseAttributeGroupDecl(child);
-            } else if (name.equals( SchemaSymbols.ELT_ATTRIBUTE ) ) {
-                traverseAttributeDecl( child, null );
-            } else if (name.equals( SchemaSymbols.ELT_WILDCARD) ) {
-                traverseWildcardDecl( child);
-            } else if (name.equals(SchemaSymbols.ELT_GROUP) && child.getAttribute(SchemaSymbols.ATT_REF).equals("")) {
-                //traverseGroupDecl(child);
-            } else if (name.equals(SchemaSymbols.ELT_NOTATION)) {
-                ; //TO DO
-            }
-            else if (name.equals(SchemaSymbols.ELT_INCLUDE)) {
-                traverseInclude(child); 
-            }
-            else if (name.equals(SchemaSymbols.ELT_IMPORT)) {
-                traverseImport(child); 
-            }
-        } // for each child node
-
-    }
-
-    private void traverseImport(Element importDecl)  throws Exception {
-        String location = importDecl.getAttribute(SchemaSymbols.ATT_SCHEMALOCATION);
-        location = expandSystemId(location, fCurrentSchemaURL);
-
-
-        String namespaceString = importDecl.getAttribute(SchemaSymbols.ATT_NAMESPACE);
-        SchemaGrammar importedGrammar = new SchemaGrammar();
-        if (fGrammarResolver.getGrammar(namespaceString) != null) {
-            importedGrammar = (SchemaGrammar) fGrammarResolver.getGrammar(namespaceString);
-        }
-
-        if (fImportLocations.contains((Object)location)) {
-            return;
-        }
-        fImportLocations.addElement((Object)location);
-
-        DOMParser parser = new DOMParser() {
-            public void ignorableWhitespace(char ch[], int start, int length) {}
-            public void ignorableWhitespace(int dataIdx) {}
-        };
-        parser.setEntityResolver( new Resolver() );
-        parser.setErrorHandler(  new ErrorHandler() );
-
-        try {
-            parser.setFeature("http://xml.org/sax/features/validation", false);
-            parser.setFeature("http://xml.org/sax/features/namespaces", true);
-            parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
-        }catch(  org.xml.sax.SAXNotRecognizedException e ) {
-            e.printStackTrace();
-        }catch( org.xml.sax.SAXNotSupportedException e ) {
-            e.printStackTrace();
-        }
-
-        try {
-            parser.parse( location);
-        }catch( IOException e ) {
-            e.printStackTrace();
-        }catch( SAXException e ) {
-            e.printStackTrace();
-        }
-
-        Document     document   = parser.getDocument(); //Our Grammar
-        Element root = null;
-        if (document != null) {
-            root = document.getDocumentElement();
-        }
-
-        if (root != null) {
-            String targetNSURI = root.getAttribute(SchemaSymbols.ATT_TARGETNAMESPACE);
-            if (!targetNSURI.equals(namespaceString) ) {
-                // REVISIT: Localize
-                reportGenericSchemaError("imported schema '"+location+"' has a different targetNameSpace '"
-                                         +targetNSURI+"' from what is declared '"+namespaceString+"'.");
-            }
-            else
-                new TraverseSchema(root, fStringPool, importedGrammar, fGrammarResolver, fErrorReporter, location);
-        }
-        else {
-            reportGenericSchemaError("Could not get the doc root for imported Schema file: "+location);
-        }
-    }
-
-/**
-     * No-op - Traverse Annotation Declaration
-     * 
-     * @param comment
-     */
-    private void traverseAnnotationDecl(Element comment) {
-        //TO DO
-        return ;
-    }
-
-    /**
-     * Traverse SimpleType declaration:
-     * <simpleType
-     *         abstract = boolean 
-     *         base = QName 
-     *         derivedBy = | list | restriction  : restriction
-     *         id = ID 
-     *         name = NCName>
-     *         Content: ( annotation? , ( minExclusive | minInclusive | maxExclusive | maxInclusive | precision | scale | length | minLength | maxLength | encoding | period | duration | enumeration | pattern )* )
-     *       </simpleType>
-     * 
-     * @param simpleTypeDecl
-     * @return 
-     */
-    private int traverseSimpleTypeDecl( Element simpleTypeDecl ) throws Exception {
-        
-        String varietyProperty       =  simpleTypeDecl.getAttribute( SchemaSymbols.ATT_DERIVEDBY );
-        if (varietyProperty.length() == 0) {
-            varietyProperty = SchemaSymbols.ATTVAL_RESTRICTION;
-        }
-        String nameProperty          =  simpleTypeDecl.getAttribute( SchemaSymbols.ATT_NAME );
-        String baseTypeQNameProperty =  simpleTypeDecl.getAttribute( SchemaSymbols.ATT_BASE );
-        String abstractProperty      =  simpleTypeDecl.getAttribute( SchemaSymbols.ATT_ABSTRACT );
-
-        int     newSimpleTypeName    = -1;
-
-
-        if ( nameProperty.equals("")) { // anonymous simpleType
-            newSimpleTypeName = fStringPool.addSymbol(
-                "#S#"+fSimpleTypeAnonCount++ );   
-                               //"http://www.apache.org/xml/xerces/internalDatatype"+fSimpleTypeAnonCount++ );   
-            } else 
-            newSimpleTypeName       = fStringPool.addSymbol( nameProperty );
-
-
-        int               basetype;
-        DatatypeValidator baseValidator = null;
-
-        if( baseTypeQNameProperty!= null ) {
-            basetype      = fStringPool.addSymbol( baseTypeQNameProperty );
-            String prefix = "";
-            String localpart = baseTypeQNameProperty;
-            int colonptr = baseTypeQNameProperty.indexOf(":");
-            if ( colonptr > 0) {
-                prefix = baseTypeQNameProperty.substring(0,colonptr);
-                localpart = baseTypeQNameProperty.substring(colonptr+1);
-            }
-            String uri = resolvePrefixToURI(prefix);
-
-            baseValidator = getDatatypeValidator(uri, localpart);
-
-            if (baseValidator == null) {
-                Element baseTypeNode = getTopLevelComponentByName(SchemaSymbols.ELT_SIMPLETYPE, localpart);
-                if (baseTypeNode != null) {
-                    traverseSimpleTypeDecl( baseTypeNode );
-                    
-                    baseValidator = getDatatypeValidator(uri, localpart);
-                    
-                    if (baseValidator == null) {
-                        reportSchemaError(SchemaMessageProvider.UnknownBaseDatatype,
-                        new Object [] { simpleTypeDecl.getAttribute( SchemaSymbols.ATT_BASE ),
-                                                          simpleTypeDecl.getAttribute(SchemaSymbols.ATT_NAME) });
-                        return -1;
-                        //reportGenericSchemaError("Base type could not be found : " + baseTypeQNameProperty);
-                    }
-
-                }
-                else {
-                    reportSchemaError(SchemaMessageProvider.UnknownBaseDatatype,
-                    new Object [] { simpleTypeDecl.getAttribute( SchemaSymbols.ATT_BASE ),
-                                                      simpleTypeDecl.getAttribute(SchemaSymbols.ATT_NAME) });
-                    return -1;
-                    //reportGenericSchemaError("Base type could not be found : " + baseTypeQNameProperty);
-                }
-                
-            }
-        }
-        // Any Children if so then check Content otherwise bail out
-
-        Element   content   = XUtil.getFirstChildElement( simpleTypeDecl );
-        int       numFacets = 0; 
-        Hashtable facetData = null;
-
-        if( content != null ) {
-
-            //Content follows: ( annotation? , facets* )
-
-            //annotation ? ( 0 or 1 )
-            if( content.getNodeName().equals( SchemaSymbols.ELT_ANNOTATION ) ){
-                traverseAnnotationDecl( content );   
-                content                    = XUtil.getNextSiblingElement(content);
-            } 
-
-            //TODO: If content is annotation again should raise validation error
-            // if( content.getNodeName().equal( SchemaSymbols.ELT_ANNOTATIO ) {
-            //   throw ValidationException(); }
-            //
-
-            //facets    * ( 0 or more )
-
-            
-            int numEnumerationLiterals = 0;
-            facetData        = new Hashtable();
-            Vector enumData            = new Vector();
-
-            while (content != null) {
-                if (content.getNodeType() == Node.ELEMENT_NODE) {
-                    Element facetElt = (Element) content;
-                    numFacets++;
-                    if (facetElt.getNodeName().equals(SchemaSymbols.ELT_ENUMERATION)) {
-                        numEnumerationLiterals++;
-                        String enumVal = facetElt.getAttribute(SchemaSymbols.ATT_VALUE);
-                        enumData.addElement(enumVal);
-                        //Enumerations can have annotations ? ( 0 | 1 )
-                        Element enumContent =  XUtil.getFirstChildElement( facetElt );
-                        if( enumContent != null && enumContent != null && enumContent.getNodeName().equals( SchemaSymbols.ELT_ANNOTATION ) ){
-                            traverseAnnotationDecl( content );   
-                         } 
-                        //TODO: If enumContent is encounter  again should raise validation error
-                        //  enumContent.getNextSibling();
-                        // if( enumContent.getNodeName().equal( SchemaSymbols.ELT_ANNOTATIO ) {
-                        //   throw ValidationException(); }
-                        //
-                    } else {
-                    facetData.put(facetElt.getNodeName(),facetElt.getAttribute( SchemaSymbols.ATT_VALUE ));
-                    }
-                }
-                //content = (Element) content.getNextSibling();
-                content = XUtil.getNextSiblingElement(content);
-            }
-            if (numEnumerationLiterals > 0) {
-               facetData.put(SchemaSymbols.ELT_ENUMERATION, enumData);
-            }
-        }
-
-        // create & register validator for "generated" type if it doesn't exist
-        
-        String nameOfType = fStringPool.toString( newSimpleTypeName);
-        if (fTargetNSURIString.length () != 0) {
-            nameOfType = fTargetNSURIString+","+nameOfType;
-        }
-                 
-
-        try {
-
-           DatatypeValidator newValidator =
-                 fDatatypeRegistry.getDatatypeValidator( nameOfType );
-
-           if( newValidator == null ) { // not previously registered
-               boolean  derivedByList = 
-                    varietyProperty.equals( SchemaSymbols.ATTVAL_LIST ) ? true:false;
-
-               fDatatypeRegistry.createDatatypeValidator( nameOfType, baseValidator,
-                              facetData, derivedByList ); 
-              
-               }
-            
-           } catch (Exception e) {
-               //e.printStackTrace(System.err);
-               reportSchemaError(SchemaMessageProvider.DatatypeError,new Object [] { e.getMessage() });
-           }
-        return fStringPool.addSymbol(nameOfType);
-    }
-
-    /*
-    * <any 
-    *   id = ID 
-    *   maxOccurs = string 
-    *   minOccurs = nonNegativeInteger 
-    *   namespace = ##any | ##other | ##local | list of {uri, ##targetNamespace} 
-    *   processContents = lax | skip | strict>
-    *   Content: (annotation?)
-    * </any>
-    */
-    private int traverseAny(Element child) throws Exception {
-        int anyIndex = -1;
-        String namespace = child.getAttribute(SchemaSymbols.ATT_NAMESPACE).trim();
-        String processContents = child.getAttribute("processContents").trim();
-
-        int processContentsAny = XMLContentSpec.CONTENTSPECNODE_ANY;
-        int processContentsAnyOther = XMLContentSpec.CONTENTSPECNODE_ANY_OTHER;
-        int processContentsAnyLocal = XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL;
-
-        if (processContents.length() > 0 && !processContents.equals("strict")) {
-            if (processContents.equals("lax")) {
-                processContentsAny = XMLContentSpec.CONTENTSPECNODE_ANY_LAX;
-                processContentsAnyOther = XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_LAX;
-                processContentsAnyLocal = XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL_LAX;
-            }
-            else if (processContents.equals("skip")) {
-                processContentsAny = XMLContentSpec.CONTENTSPECNODE_ANY_SKIP;
-                processContentsAnyOther = XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_SKIP;
-                processContentsAnyLocal = XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL_SKIP;
-            }
-        }
-
-        if (namespace.length() == 0 || namespace.equals("##any")) {
-            anyIndex = fSchemaGrammar.addContentSpecNode(processContentsAny, -1, -1, false);
-        }
-        else if (namespace.equals("##other")) {
-            String uri = child.getOwnerDocument().getDocumentElement().getAttribute("targetNamespace");
-            int uriIndex = fStringPool.addSymbol(uri);
-            anyIndex = fSchemaGrammar.addContentSpecNode(processContentsAnyOther, -1, uriIndex, false);
-        }
-        else if (namespace.equals("##local")) {
-            anyIndex = fSchemaGrammar.addContentSpecNode(processContentsAnyLocal, -1, -1, false);
-        }
-        else if (namespace.length() > 0) {
-            StringTokenizer tokenizer = new StringTokenizer(namespace);
-            Vector tokens = new Vector();
-            while (tokenizer.hasMoreElements()) {
-                String token = tokenizer.nextToken();
-                if (token.equals("##targetNamespace")) {
-                    token = child.getOwnerDocument().getDocumentElement().getAttribute("targetNamespace");
-                }
-                tokens.addElement(token);
-            }
-            String uri = (String)tokens.elementAt(0);
-            int uriIndex = fStringPool.addSymbol(uri);
-            int leafIndex = fSchemaGrammar.addContentSpecNode(processContentsAny, -1, uriIndex, false);
-            int valueIndex = leafIndex;
-            int count = tokens.size();
-            if (count > 1) {
-                uri = (String)tokens.elementAt(1);
-                uriIndex = fStringPool.addSymbol(uri);
-                leafIndex = fSchemaGrammar.addContentSpecNode(processContentsAny, -1, uriIndex, false);
-                int otherValueIndex = leafIndex;
-                int choiceIndex = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE, valueIndex, otherValueIndex, false);
-                for (int i = 2; i < count; i++) {
-                    uri = (String)tokens.elementAt(i);
-                    uriIndex = fStringPool.addSymbol(uri);
-                    leafIndex = fSchemaGrammar.addContentSpecNode(processContentsAny, -1, uriIndex, false);
-                    otherValueIndex = leafIndex;
-                    choiceIndex = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE, choiceIndex, otherValueIndex, false);
-                }
-                anyIndex = choiceIndex;
-            }
-            else {
-                anyIndex = leafIndex;
-            }
-        }
-        else {
-            // REVISIT: Localize
-            reportGenericSchemaError("Empty namespace attribute for any element");
-        }
-
-        return anyIndex;
-    }
-
-
-    public DatatypeValidator getDatatypeValidator(String uri, String localpart) {
-
-        DatatypeValidator dv = null;
-
-        if (uri.length()==0 || uri.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) {
-            dv = fDatatypeRegistry.getDatatypeValidator( localpart );
-        }
-        else {
-            dv = fDatatypeRegistry.getDatatypeValidator( uri+","+localpart );
-        }
-
-        return dv;
-    }
-
-    /*
-    * <anyAttribute 
-    *   id = ID 
-    *   namespace = ##any | ##other | ##local | list of {uri, ##targetNamespace}>
-    *   Content: (annotation?)
-    * </anyAttribute>
-    */
-    private XMLAttributeDecl traverseAnyAttribute(Element anyAttributeDecl) throws Exception {
-        XMLAttributeDecl anyAttDecl = new XMLAttributeDecl();
-        String processContents = anyAttributeDecl.getAttribute(SchemaSymbols.ATT_PROCESSCONTENTS).trim();
-        String namespace = anyAttributeDecl.getAttribute(SchemaSymbols.ATT_NAMESPACE).trim();
-        String curTargetUri = anyAttributeDecl.getOwnerDocument().getDocumentElement().getAttribute("targetNamespace");
-
-        if ( namespace.length() == 0 || namespace.equals(SchemaSymbols.ATTVAL_TWOPOUNDANY) ) {
-            anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_ANY;
-        } 
-        else if (namespace.equals(SchemaSymbols.ATTVAL_TWOPOUNDOTHER)) {
-            anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_OTHER;
-            anyAttDecl.name.uri = fStringPool.addSymbol(curTargetUri);
-        }
-        else if (namespace.equals(SchemaSymbols.ATTVAL_TWOPOUNDLOCAL)) {
-            anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_LOCAL;
-        }
-        else if (namespace.length() > 0){
-            anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_LIST;
-
-            StringTokenizer tokenizer = new StringTokenizer(namespace);
-            int aStringList = fStringPool.startStringList();
-            Vector tokens = new Vector();
-            while (tokenizer.hasMoreElements()) {
-                String token = tokenizer.nextToken();
-                if (token.equals("##targetNamespace")) {
-                    token = curTargetUri;
-                }
-                if (!fStringPool.addStringToList(aStringList, fStringPool.addSymbol(token))){
-                    reportGenericSchemaError("Internal StringPool error when reading the "+
-                                             "namespace attribute for anyattribute declaration");
-                }
-            }
-            fStringPool.finishStringList(aStringList);
-
-            anyAttDecl.enumeration = aStringList;
-        }
-        else {
-            // REVISIT: Localize
-            reportGenericSchemaError("Empty namespace attribute for anyattribute declaration");
-        }
-
-        // default processContents is "strict";
-        anyAttDecl.defaultType = XMLAttributeDecl.PROCESSCONTENTS_STRICT;
-
-        if (processContents.equals(SchemaSymbols.ATTVAL_SKIP)){
-            anyAttDecl.defaultType = XMLAttributeDecl.PROCESSCONTENTS_SKIP;
-        }
-        else if (processContents.equals(SchemaSymbols.ATTVAL_LAX)) {
-            anyAttDecl.defaultType = XMLAttributeDecl.PROCESSCONTENTS_LAX;
-        }
-
-        return anyAttDecl; 
-    }
-
-    private XMLAttributeDecl mergeTwoAnyAttribute(XMLAttributeDecl oneAny, XMLAttributeDecl anotherAny) {
-        if (oneAny.type == -1) {
-            return oneAny;
-        }
-        if (anotherAny.type == -1) {
-            return anotherAny;
-        }
-
-        if (oneAny.type == XMLAttributeDecl.TYPE_ANY_ANY) {
-            return anotherAny;
-        }
-
-        if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_ANY) {
-            return oneAny;
-        }
-
-        if (oneAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
-            if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
-
-                if ( anotherAny.name.uri == oneAny.name.uri ) {
-                    return oneAny;
-                }
-                else {
-                    oneAny.type = -1;
-                    return oneAny;
-                }
-
-            }
-            else if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_LOCAL) {
-                return anotherAny;
-            }
-            else if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
-                if (!fStringPool.stringInList(anotherAny.enumeration, oneAny.name.uri) ) {
-                    return anotherAny;
-                }
-                else {
-                    int[] anotherAnyURIs = fStringPool.stringListAsIntArray(anotherAny.enumeration);
-                    int newList = fStringPool.startStringList();
-                    for (int i=0; i< anotherAnyURIs.length; i++) {
-                        if (anotherAnyURIs[i] != oneAny.name.uri ) {
-                            fStringPool.addStringToList(newList, anotherAnyURIs[i]);
-                        }
-                    }
-                    fStringPool.finishStringList(newList);
-                    anotherAny.enumeration = newList;
-                    return anotherAny;
-                }
-            }
-        }
-
-        if (oneAny.type == XMLAttributeDecl.TYPE_ANY_LOCAL) {
-            if ( anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER
-                || anotherAny.type == XMLAttributeDecl.TYPE_ANY_LOCAL) {
-                return oneAny;
-            }
-            else if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
-                oneAny.type = -1;
-                return oneAny;
-            }
-        }
-
-        if (oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
-            if ( anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER){
-                if (!fStringPool.stringInList(oneAny.enumeration, anotherAny.name.uri) ) {
-                    return oneAny;
-                }
-                else {
-                    int[] oneAnyURIs = fStringPool.stringListAsIntArray(oneAny.enumeration);
-                    int newList = fStringPool.startStringList();
-                    for (int i=0; i< oneAnyURIs.length; i++) {
-                        if (oneAnyURIs[i] != anotherAny.name.uri ) {
-                            fStringPool.addStringToList(newList, oneAnyURIs[i]);
-                        }
-                    }
-                    fStringPool.finishStringList(newList);
-                    oneAny.enumeration = newList;
-                    return oneAny;
-                }
-
-            }
-            else if ( anotherAny.type == XMLAttributeDecl.TYPE_ANY_LOCAL) {
-                oneAny.type = -1;
-                return oneAny;
-            }
-            else if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
-                int[] result = intersect2sets( fStringPool.stringListAsIntArray(oneAny.enumeration), 
-                                               fStringPool.stringListAsIntArray(anotherAny.enumeration));
-                int newList = fStringPool.startStringList();
-                for (int i=0; i<result.length; i++) {
-                    fStringPool.addStringToList(newList, result[i]);
-                }
-                fStringPool.finishStringList(newList);
-                oneAny.enumeration = newList;
-                return oneAny;
-            }
-        }
-
-        // should never go there;
-        return oneAny;
-    }
-
-    int[] intersect2sets(int[] one, int[] theOther){
-        int[] result = new int[(one.length>theOther.length?one.length:theOther.length)];
-
-        // simple implemention, 
-        int count = 0;
-        for (int i=0; i<one.length; i++) {
-            for(int j=0; j<theOther.length; j++) {
-                if (one[i]==theOther[j]) {
-                    result[count++] = one[i];
-                }
-            }
-        }
-
-        int[] result2 = new int[count];
-        System.arraycopy(result, 0, result2, 0, count);
-
-        return result2;
-    }
-
-    /**
-     * Traverse ComplexType Declaration.
-     *  
-     *       <complexType 
-     *         abstract = boolean 
-     *         base = QName 
-     *         block = #all or (possibly empty) subset of {extension, restriction} 
-     *         content = elementOnly | empty | mixed | textOnly 
-     *         derivedBy = extension | restriction 
-     *         final = #all or (possibly empty) subset of {extension, restriction} 
-     *         id = ID 
-     *         name = NCName>
-     *          Content: (annotation? , (((minExclusive | minInclusive | maxExclusive
-     *                    | maxInclusive | precision | scale | length | minLength 
-     *                    | maxLength | encoding | period | duration | enumeration 
-     *                    | pattern)* | (element | group | all | choice | sequence | any)*) , 
-     *                    ((attribute | attributeGroup)* , anyAttribute?)))
-     *        </complexType>
-     * @param complexTypeDecl
-     * @return 
-     */
-    
-    //REVISIT: TO DO, base and derivation ???
-    private int traverseComplexTypeDecl( Element complexTypeDecl ) throws Exception { 
-        String isAbstract = complexTypeDecl.getAttribute( SchemaSymbols.ATT_ABSTRACT );
-        String base = complexTypeDecl.getAttribute(SchemaSymbols.ATT_BASE);
-        String blockSet = complexTypeDecl.getAttribute( SchemaSymbols.ATT_BLOCK );
-        String content = complexTypeDecl.getAttribute(SchemaSymbols.ATT_CONTENT);
-        String derivedBy = complexTypeDecl.getAttribute( SchemaSymbols.ATT_DERIVEDBY );
-        String finalSet = complexTypeDecl.getAttribute( SchemaSymbols.ATT_FINAL );
-        String typeId = complexTypeDecl.getAttribute( SchemaSymbols.ATTVAL_ID );
-        String typeName = complexTypeDecl.getAttribute(SchemaSymbols.ATT_NAME); 
-        boolean isNamedType = false;
-
-        if ( DEBUGGING )
-            System.out.println("traversing complex Type : " + typeName +","+base+","+content+".");
-
-        if (typeName.equals("")) { // gensym a unique name
-            //typeName = "http://www.apache.org/xml/xerces/internalType"+fTypeCount++;
-            typeName = "#"+fAnonTypeCount++;
-        }
-        else {
-            fCurrentTypeNameStack.push(typeName);
-            isNamedType = true;
-        }
-
-        if (isTopLevel(complexTypeDecl)) {
-        
-            String fullName = fTargetNSURIString+","+typeName;
-            ComplexTypeInfo temp = (ComplexTypeInfo) fComplexTypeRegistry.get(fullName);
-            if (temp != null ) {
-                return fStringPool.addSymbol(fullName);
-            }
-        }
-
-        int scopeDefined = fScopeCount++;
-        int previousScope = fCurrentScope;
-        fCurrentScope = scopeDefined;
-
-        Element child = null;
-        int contentSpecType = -1;
-        int csnType = 0;
-        int left = -2;
-        int right = -2;
-
-        ComplexTypeInfo baseTypeInfo = null;  //if base is a complexType;
-        DatatypeValidator baseTypeValidator = null; //if base is a simple type or a complex type derived from a simpleType
-        DatatypeValidator simpleTypeValidator = null;
-        int baseTypeSymbol = -1;
-        String fullBaseName = "";
-
-        boolean baseIsSimpleSimple = false;
-        boolean baseIsComplexSimple = false;
-        boolean baseFromAnotherSchema = false;
-        String baseTypeSchemaURI = null;
-        boolean derivedByRestriction = true;
-        boolean derivedByExtension = false;
-        int baseContentSpecHandle = -1;
-        Element baseTypeNode = null;
-
-
-        //int parsedderivedBy = parseComplexDerivedBy(derivedBy);
-        //handle the inhreitance here. 
-        if (base.length()>0) {
-
-            //first check if derivedBy is present
-            if (derivedBy.length() == 0) {
-                // REVISIT: Localize
-                reportGenericSchemaError("derivedBy must be present when base is present in " 
-                                         +SchemaSymbols.ELT_COMPLEXTYPE
-                                         +" "+ typeName);
-                derivedBy = SchemaSymbols.ATTVAL_EXTENSION;
-            }
-
-            if (derivedBy.equals(SchemaSymbols.ATTVAL_EXTENSION)) {
-                derivedByRestriction = false;
-            }
-
-            String prefix = "";
-            String localpart = base;
-            int colonptr = base.indexOf(":");
-            if ( colonptr > 0) {
-                prefix = base.substring(0,colonptr);
-                localpart = base.substring(colonptr+1);
-            }
-            int localpartIndex = fStringPool.addSymbol(localpart);
-            String typeURI = resolvePrefixToURI(prefix);
-
-            // check if the base type is from the same Schema;
-            if ( ! typeURI.equals(fTargetNSURIString) 
-                 && ! typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) 
-                 && typeURI.length() != 0 )  /*REVISIT, !!!! a hack: for schema that has no target namespace, e.g. personal-schema.xml*/{
-                baseFromAnotherSchema = true;
-                baseTypeSchemaURI = typeURI;
-                baseTypeInfo = getTypeInfoFromNS(typeURI, localpart);
-                if (baseTypeInfo == null) {
-                    baseTypeValidator = getTypeValidatorFromNS(typeURI, localpart);
-                    if (baseTypeValidator == null) {
-                        //TO DO: report error here;
-                        System.out.println("Could not find base type " +localpart 
-                                           + " in schema " + typeURI);
-                    }
-                    else{
-                        baseIsSimpleSimple = true;
-                    }
-                }
-            }
-            else {
-
-                fullBaseName = typeURI+","+localpart;
-
-                // assume the base is a complexType and try to locate the base type first
-                baseTypeInfo = (ComplexTypeInfo) fComplexTypeRegistry.get(fullBaseName);
-
-                // if not found, 2 possibilities: 1: ComplexType in question has not been compiled yet;
-                //                                2: base is SimpleTYpe;
-                if (baseTypeInfo == null) {
-                    baseTypeValidator = getDatatypeValidator(typeURI, localpart);
-
-                    if (baseTypeValidator == null) {
-                        baseTypeNode = getTopLevelComponentByName(SchemaSymbols.ELT_COMPLEXTYPE,localpart);
-                        if (baseTypeNode != null) {
-                            baseTypeSymbol = traverseComplexTypeDecl( baseTypeNode );
-                            baseTypeInfo = (ComplexTypeInfo)
-                            fComplexTypeRegistry.get(fStringPool.toString(baseTypeSymbol)); //REVISIT: should it be fullBaseName;
-                        }
-                        else {
-                            baseTypeNode = getTopLevelComponentByName(SchemaSymbols.ELT_SIMPLETYPE, localpart);
-                            if (baseTypeNode != null) {
-                                    baseTypeSymbol = traverseSimpleTypeDecl( baseTypeNode );
-                                    simpleTypeValidator = baseTypeValidator = getDatatypeValidator(typeURI, localpart);
-                                    if (simpleTypeValidator == null) {
-                                        //TO DO: signal error here.
-                                    }
-
-                                    baseIsSimpleSimple = true;
-                            }
-                            else {
-                                // REVISIT: Localize
-                                reportGenericSchemaError("Base type could not be found : " + base);
-                            }
-                        }
-                    }
-                    else {
-                        simpleTypeValidator = baseTypeValidator;
-                        baseIsSimpleSimple = true;
-                    }
-                }
-            }
-            //Schema Spec : 5.11: Complex Type Definition Properties Correct : 2
-            if (baseIsSimpleSimple && derivedByRestriction) {
-                // REVISIT: Localize
-                reportGenericSchemaError("base is a simpledType, can't derive by restriction in " + typeName); 
-            }
-
-            //if  the base is a complexType
-            if (baseTypeInfo != null ) {
-
-                //Schema Spec : 5.11: Derivation Valid ( Extension ) 1.1.1
-                //              5.11: Derivation Valid ( Restriction, Complex ) 1.2.1
-                if (derivedByRestriction) {
-                    //REVISIT: check base Type's finalset does not include "restriction"
-                }
-                else {
-                    //REVISIT: check base Type's finalset doest not include "extension"
-                }
-
-                if ( baseTypeInfo.contentSpecHandle > -1) {
-                    if (derivedByRestriction) {
-                        //REVISIT: !!! really hairy staff to check the particle derivation OK in 5.10
-                        checkParticleDerivationOK(complexTypeDecl, baseTypeNode);
-                    }
-                    baseContentSpecHandle = baseTypeInfo.contentSpecHandle;
-                }
-                else if ( baseTypeInfo.datatypeValidator != null ) {
-                    baseTypeValidator = baseTypeInfo.datatypeValidator;
-                    baseIsComplexSimple = true;
-                }
-            }
-
-            //Schema Spec : 5.11: Derivation Valid ( Extension ) 1.1.1
-            if (baseIsComplexSimple && !derivedByRestriction ) {
-                // REVISIT: Localize
-                reportGenericSchemaError("base is ComplexSimple, can't derive by extension in " + typeName);
-            }
-
-
-        } // END of if (base.length() > 0) {}
-
-        // skip refinement and annotations
-        child = null;
-
-        if (baseIsComplexSimple) {
-
-            contentSpecType = XMLElementDecl.TYPE_SIMPLE;
-            
-            int numEnumerationLiterals = 0;
-            int numFacets = 0;
-            Hashtable facetData        = new Hashtable();
-            Vector enumData            = new Vector();
-
-
-            //REVISIT: there is a better way to do this, 
-            for (child = XUtil.getFirstChildElement(complexTypeDecl);
-                 child != null && (child.getNodeName().equals(SchemaSymbols.ELT_MINEXCLUSIVE) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_MININCLUSIVE) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_MAXEXCLUSIVE) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_MAXINCLUSIVE) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_PRECISION) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_SCALE) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_LENGTH) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_MINLENGTH) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_MAXLENGTH) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_ENCODING) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_PERIOD) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_DURATION) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_ENUMERATION) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_PATTERN) ||
-                                   child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION));
-                 child = XUtil.getNextSiblingElement(child)) 
-            {
-                if ( child.getNodeType() == Node.ELEMENT_NODE ) {
-                    Element facetElt = (Element) child;
-                    numFacets++;
-                    if (facetElt.getNodeName().equals(SchemaSymbols.ELT_ENUMERATION)) {
-                        numEnumerationLiterals++;
-                        enumData.addElement(facetElt.getAttribute(SchemaSymbols.ATT_VALUE));
-                        //Enumerations can have annotations ? ( 0 | 1 )
-                        Element enumContent =  XUtil.getFirstChildElement( facetElt );
-                        if( enumContent != null && enumContent.getNodeName().equals( SchemaSymbols.ELT_ANNOTATION ) ){
-                            traverseAnnotationDecl( child );   
-                        }
-                        // TO DO: if Jeff check in new changes to TraverseSimpleType, copy them over
-                    } else {
-                        facetData.put(facetElt.getNodeName(),facetElt.getAttribute( SchemaSymbols.ATT_VALUE ));
-                    }
-                }
-            }
-            if (numEnumerationLiterals > 0) {
-                facetData.put(SchemaSymbols.ELT_ENUMERATION, enumData);
-            }
-
-            //if (numFacets > 0)
-            //    baseTypeValidator.setFacets(facetData, derivedBy );
-            if (numFacets > 0) {
-                simpleTypeValidator = fDatatypeRegistry.createDatatypeValidator( typeName, baseTypeValidator,
-                                                           facetData, false ); 
-            }
-            else
-                simpleTypeValidator = baseTypeValidator;
-
-            if (child != null) {
-                // REVISIT: Localize
-                reportGenericSchemaError("Invalid child '"+child.getNodeName()+"' in complexType : '" + typeName 
-                                         + "', because it restricts another complexSimpleType");
-            }
-        }
-
-            // if content = textonly, base is a datatype
-        if (content.equals(SchemaSymbols.ATTVAL_TEXTONLY)) {
-            //TO DO
-            if (base.length() == 0) {
-                simpleTypeValidator = baseTypeValidator = getDatatypeValidator("", SchemaSymbols.ATTVAL_STRING);
-            }
-            else if ( baseTypeValidator == null 
-                      && baseTypeInfo != null && baseTypeInfo.datatypeValidator==null ) // must be datatype
-                        reportSchemaError(SchemaMessageProvider.NotADatatype,
-                                          new Object [] { base }); //REVISIT check forward refs
-            //handle datatypes
-            contentSpecType = XMLElementDecl.TYPE_SIMPLE;
-            /****
-            left = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_LEAF,
-                                                 fStringPool.addSymbol(base),
-                                                 -1, false);
-            /****/                                                 
-
-        } 
-        else {   
-            if (!baseIsComplexSimple) {
-                contentSpecType = XMLElementDecl.TYPE_CHILDREN;
-            }
-            csnType = XMLContentSpec.CONTENTSPECNODE_SEQ;
-            boolean mixedContent = false;
-            //REVISIT: is the default content " elementOnly"
-            boolean elementContent = true;
-            boolean textContent = false;
-            boolean emptyContent = false;
-            left = -2;
-            right = -2;
-            boolean hadContent = false;
-
-            if (content.equals(SchemaSymbols.ATTVAL_EMPTY)) {
-                contentSpecType = XMLElementDecl.TYPE_EMPTY;
-                emptyContent = true;
-                elementContent = false;
-                left = -1; // no contentSpecNode needed
-            } else if (content.equals(SchemaSymbols.ATTVAL_MIXED) ) {
-                contentSpecType = XMLElementDecl.TYPE_MIXED;
-                mixedContent = true;
-                elementContent = false;
-                csnType = XMLContentSpec.CONTENTSPECNODE_CHOICE;
-            } else if (content.equals(SchemaSymbols.ATTVAL_ELEMENTONLY) || content.equals("")) {
-                elementContent = true;
-            } else if (content.equals(SchemaSymbols.ATTVAL_TEXTONLY)) {
-                textContent = true;
-                elementContent = false;
-            }
-
-            if (mixedContent) {
-                // add #PCDATA leaf
-
-                left = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_LEAF,
-                                                         -1, // -1 means "#PCDATA" is name
-                                                         -1, false);
-                csnType = XMLContentSpec.CONTENTSPECNODE_CHOICE;
-            }
-
-            boolean seeParticle = false;
-            boolean seeOtherParticle = false;                
-            boolean seeAll = false;
-
-            for (child = XUtil.getFirstChildElement(complexTypeDecl);
-                 child != null;
-                 child = XUtil.getNextSiblingElement(child)) {
-
-                int index = -2;  // to save the particle's contentSpec handle 
-                hadContent = true;
-
-                seeParticle = false;
-
-                String childName = child.getNodeName();
-
-                if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
-                    if (mixedContent || elementContent) {
-                        if ( DEBUGGING )
-                            System.out.println(" child element name " + child.getAttribute(SchemaSymbols.ATT_NAME));
-
-                        QName eltQName = traverseElementDecl(child);
-                        index = fSchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_LEAF,
-                                                                   eltQName.localpart,
-                                                                   eltQName.uri, 
-                                                                   false);
-                        seeParticle = true;
-                        seeOtherParticle = true;
-
-                    } 
-                    else {
-                        reportSchemaError(SchemaMessageProvider.EltRefOnlyInMixedElemOnly, null);
-                    }
-
-                } 
-                else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
-                    index = traverseGroupDecl(child);
-                    seeParticle = true;
-                    seeOtherParticle = true;
-                } 
-                else if (childName.equals(SchemaSymbols.ELT_ALL)) {
-                    index = traverseAll(child);
-                    seeParticle = true;
-                    seeAll = true;
-                  
-                } 
-                else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
-                    index = traverseChoice(child);
-                    seeParticle = true;
-                    seeOtherParticle = true;                  
-                } 
-                else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
-                    index = traverseSequence(child);
-                    seeParticle = true;
-                    seeOtherParticle = true;                  
-                } 
-                else if (childName.equals(SchemaSymbols.ELT_ATTRIBUTE) ||
-                           childName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
-                    break; // attr processing is done later on in this method
-                } 
-                else if (childName.equals(SchemaSymbols.ELT_ANY)) {
-
-                    index = traverseAny(child);
-                    seeParticle = true;
-                    seeOtherParticle = true;
-                } 
-                else if (childName.equals(SchemaSymbols.ELT_ANNOTATION)) {
-                    //REVISIT, do nothing for annotation for now.
-                } 
-                else if (childName.equals(SchemaSymbols.ELT_ANYATTRIBUTE)) {
-                    break;
-                    //REVISIT, do nothing for attribute wildcard for now.
-                } 
-                else { // datatype qual 
-                    if (!baseIsComplexSimple ) 
-                    if (base.equals(""))
-                        reportSchemaError(SchemaMessageProvider.GenericError, 
-                                          new Object [] { "unrecognized child '"+childName+"' in complex type "+typeName });
-                    else
-                        reportSchemaError(SchemaMessageProvider.GenericError,
-                                          new Object [] { "unrecognized child '"+childName+"' in complex type '"+typeName+"' with base "+base  });
-                }
-
-                // if base is complextype with simpleType content, can't have any particle children at all.
-                if (baseIsComplexSimple && seeParticle) {
-                    // REVISIT: Localize
-                    reportGenericSchemaError("In complexType "+typeName+", base type is complexType with simpleType content, can't have any particle children at all");
-                    hadContent = false;
-                    left = index = -2;
-                    contentSpecType = XMLElementDecl.TYPE_SIMPLE;
-                    break;
-                }
-
-
-                if (seeAll && seeOtherParticle) {
-                    // REVISIT: Localize
-                    reportGenericSchemaError ( " 'All' group needs to be the only child in Complextype : " + typeName);
-                }
-
-                if (seeAll) {
-                    //TO DO: REVISIT 
-                    //check the minOccurs = 1 and maxOccurs = 1  
-                }
-
-                // check the minOccurs and maxOccurs of the particle, and fix the  
-                // contentspec accordingly
-                if (seeParticle) {
-                    index = expandContentModel(index, child);
-                    if (index == -2 ) {
-                        continue;
-                    }
-                } //end of if (seeParticle)
-
-                if (left == -2) {
-                    left = index;
-                } else if (right == -2) {
-                    right = index;
-                } else {
-                    left = fSchemaGrammar.addContentSpecNode(csnType, left, right, false);
-                    right = index;
-                }
-            } //end looping through the children
-
-            if ( ! ( seeOtherParticle || seeAll ) && (elementContent || mixedContent)
-                 &&  (base.length() == 0 || ( base.length() > 0 && derivedByRestriction && !baseIsComplexSimple))  ) {
-                contentSpecType = XMLElementDecl.TYPE_SIMPLE;
-                simpleTypeValidator = getDatatypeValidator("", SchemaSymbols.ATTVAL_STRING);
-                // REVISIT: Localize
-                reportGenericSchemaError ( " complexType '"+typeName+"' with a elementOnly or mixed content "
-                                           +"need to have at least one particle child");
-            }
-
-            if (hadContent && right != -2)
-                left = fSchemaGrammar.addContentSpecNode(csnType, left, right, false);
-
-            if (mixedContent && hadContent) {
-                // set occurrence count
-                left = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE,
-                                                     left, -1, false);
-            }
-        }
-
-        // if derived by extension and base complextype has a content model, 
-        // compose the final content model by concatenating the base and the 
-        // current in sequence.
-        if (!derivedByRestriction && baseContentSpecHandle > -1 ) {
-            if (left == -2) {
-                left = baseContentSpecHandle;
-            }
-            else 
-                left = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ, 
-                                                         baseContentSpecHandle,
-                                                         left,
-                                                         false);
-        }
-
-        // REVISIT: this is when sees a topelevel <complexType name="abc">attrs*</complexType>
-        if (content.length() == 0 && base.length() == 0 && left == -2) {
-            contentSpecType = XMLElementDecl.TYPE_ANY;
-        }
-
-        if (content.length() == 0 && simpleTypeValidator == null && left == -2 ) {
-            if (base.length() > 0 && baseTypeInfo != null 
-                && baseTypeInfo.contentType == XMLElementDecl.TYPE_EMPTY) {
-                contentSpecType = XMLElementDecl.TYPE_EMPTY;
-            }
-        }
-
-        if ( DEBUGGING )
-            System.out.println("!!!!!>>>>>" + typeName+", "+ baseTypeInfo + ", " 
-                               + baseContentSpecHandle +", " + left +", "+scopeDefined);
-
-        ComplexTypeInfo typeInfo = new ComplexTypeInfo();
-        typeInfo.baseComplexTypeInfo = baseTypeInfo;
-        typeInfo.baseDataTypeValidator = baseTypeValidator;
-        int derivedByInt = -1;
-        if (derivedBy.length() > 0) {
-            derivedByInt = parseComplexDerivedBy(derivedBy);
-        }
-        typeInfo.derivedBy = derivedByInt;
-        typeInfo.scopeDefined = scopeDefined; 
-        typeInfo.contentSpecHandle = left;
-        typeInfo.contentType = contentSpecType;
-        typeInfo.datatypeValidator = simpleTypeValidator;
-        typeInfo.blockSet = parseBlockSet(complexTypeDecl.getAttribute(SchemaSymbols.ATT_BLOCK));
-        typeInfo.finalSet = parseFinalSet(complexTypeDecl.getAttribute(SchemaSymbols.ATT_FINAL));
-        typeInfo.isAbstract = isAbstract.equals(SchemaSymbols.ATTVAL_TRUE) ? true:false ;
-
-        //add a template element to the grammar element decl pool.
-        int typeNameIndex = fStringPool.addSymbol(typeName);
-        int templateElementNameIndex = fStringPool.addSymbol("$"+typeName);
-
-        typeInfo.templateElementIndex = 
-            fSchemaGrammar.addElementDecl(new QName(-1, templateElementNameIndex,typeNameIndex,fTargetNSURI),
-                                          (fTargetNSURI==-1) ? -1 : fCurrentScope, scopeDefined,
-                                            contentSpecType, left, 
-                                          -1, simpleTypeValidator);
-        typeInfo.attlistHead = fSchemaGrammar.getFirstAttributeDeclIndex(typeInfo.templateElementIndex);
-
-
-        // (attribute | attrGroupRef)*
-        XMLAttributeDecl attWildcard = null;
-        Vector anyAttDecls = new Vector();
-
-        for (child = XUtil.getFirstChildElement(complexTypeDecl);
-             child != null;
-             child = XUtil.getNextSiblingElement(child)) {
-
-            String childName = child.getNodeName();
-
-            if (childName.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
-                if ((baseIsComplexSimple||baseIsSimpleSimple) && derivedByRestriction) {
-                    // REVISIT: Localize
-                    reportGenericSchemaError("In complexType "+typeName+
-                                             ", base type has simpleType "+
-                                             "content and derivation method is"+
-                                             " 'restriction', can't have any "+
-                                             "attribute children at all");
-                    break;
-                }
-                traverseAttributeDecl(child, typeInfo);
-            } 
-            else if ( childName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP) ) { 
-                if ((baseIsComplexSimple||baseIsSimpleSimple) && derivedByRestriction) {
-                    // REVISIT: Localize
-                    reportGenericSchemaError("In complexType "+typeName+", base "+
-                                             "type has simpleType content and "+
-                                             "derivation method is 'restriction',"+
-                                             " can't have any attribute children at all");
-                    break;
-                }
-                traverseAttributeGroupDecl(child,typeInfo,anyAttDecls);
-            }
-            else if ( childName.equals(SchemaSymbols.ELT_ANYATTRIBUTE) ) { 
-                attWildcard = traverseAnyAttribute(child);
-            }
-        }
-
-        if (attWildcard != null) {
-            XMLAttributeDecl fromGroup = null;
-            final int count = anyAttDecls.size();
-            if ( count > 0) {
-                fromGroup = (XMLAttributeDecl) anyAttDecls.elementAt(0);
-                for (int i=1; i<count; i++) {
-                    fromGroup = mergeTwoAnyAttribute(fromGroup,(XMLAttributeDecl)anyAttDecls.elementAt(i));
-                }
-            }
-            if (fromGroup != null) {
-                int saveProcessContents = attWildcard.defaultType;
-                attWildcard = mergeTwoAnyAttribute(attWildcard, fromGroup);
-                attWildcard.defaultType = saveProcessContents;
-            }
-        }
-        else {
-            //REVISIT: unclear in the Scheme Structures 4.3.3 what to do in this case
-        }
-
-        // merge in base type's attribute decls
-        XMLAttributeDecl baseAttWildcard = null;
-        if (baseTypeInfo != null && baseTypeInfo.attlistHead > -1 ) {
-            int attDefIndex = baseTypeInfo.attlistHead;
-            SchemaGrammar aGrammar = fSchemaGrammar;
-            if (baseFromAnotherSchema) {
-                aGrammar = (SchemaGrammar) fGrammarResolver.getGrammar(baseTypeSchemaURI);
-            }
-            if (aGrammar == null) {
-                reportGenericSchemaError("In complexType "+typeName+", can NOT find the grammar "+
-                                         "with targetNamespace" + baseTypeSchemaURI+
-                                         "for the base type");
-            }
-            else
-            while ( attDefIndex > -1 ) {
-                fTempAttributeDecl.clear();
-                aGrammar.getAttributeDecl(attDefIndex, fTempAttributeDecl);
-                if (fTempAttributeDecl.type == XMLAttributeDecl.TYPE_ANY_ANY 
-                    ||fTempAttributeDecl.type == XMLAttributeDecl.TYPE_ANY_LIST
-                    ||fTempAttributeDecl.type == XMLAttributeDecl.TYPE_ANY_LOCAL 
-                    ||fTempAttributeDecl.type == XMLAttributeDecl.TYPE_ANY_OTHER ) {
-                    if (attWildcard == null) {
-                        baseAttWildcard = fTempAttributeDecl;
-                    }
-                    attDefIndex = aGrammar.getNextAttributeDeclIndex(attDefIndex);
-                    continue;
-                }
-                // if found a duplicate, if it is derived by restriction. then skip the one from the base type
-                /**/
-                int temp = fSchemaGrammar.getAttributeDeclIndex(typeInfo.templateElementIndex, fTempAttributeDecl.name);
-                if ( temp > -1) {
-                    if (derivedByRestriction) {
-                        attDefIndex = fSchemaGrammar.getNextAttributeDeclIndex(attDefIndex);
-                        continue;
-                    }
-                }
-
-                /**/
-                fSchemaGrammar.addAttDef( typeInfo.templateElementIndex, 
-                                          fTempAttributeDecl.name, fTempAttributeDecl.type, 
-                                          fTempAttributeDecl.enumeration, fTempAttributeDecl.defaultType, 
-                                          fTempAttributeDecl.defaultValue, 
-                                          fTempAttributeDecl.datatypeValidator,
-                                          fTempAttributeDecl.list);
-                attDefIndex = aGrammar.getNextAttributeDeclIndex(attDefIndex);
-            }
-        }
-        // att wildcard will inserted after all attributes were processed
-        if (attWildcard != null) {
-            if (attWildcard.type != -1) {
-                fSchemaGrammar.addAttDef( typeInfo.templateElementIndex, 
-                                          attWildcard.name, attWildcard.type, 
-                                          attWildcard.enumeration, attWildcard.defaultType, 
-                                          attWildcard.defaultValue, 
-                                          attWildcard.datatypeValidator,
-                                          attWildcard.list);
-            }
-            else {
-                //REVISIT: unclear in Schema spec if should report error here.
-            }
-        }
-        else if (baseAttWildcard != null) {
-            fSchemaGrammar.addAttDef( typeInfo.templateElementIndex, 
-                                      baseAttWildcard.name, baseAttWildcard.type, 
-                                      baseAttWildcard.enumeration, baseAttWildcard.defaultType, 
-                                      baseAttWildcard.defaultValue, 
-                                      baseAttWildcard.datatypeValidator,
-                                      baseAttWildcard.list);
-        }
-
-        typeInfo.attlistHead = fSchemaGrammar.getFirstAttributeDeclIndex(typeInfo.templateElementIndex);
-
-        if (!typeName.startsWith("#")) {
-            typeName = fTargetNSURIString + "," + typeName;
-        }
-        typeInfo.typeName = new String(typeName);
-        if ( DEBUGGING )
-            System.out.println("add complex Type to Registry: " + typeName +","+content+".");
-        fComplexTypeRegistry.put(typeName,typeInfo);
-
-        // before exit the complex type definition, restore the scope, mainly for nested Anonymous Types
-        fCurrentScope = previousScope;
-        if (isNamedType) {
-            fCurrentTypeNameStack.pop();
-            checkRecursingComplexType();
-        }
-
-        //set template element's typeInfo
-        fSchemaGrammar.setElementComplexTypeInfo(typeInfo.templateElementIndex, typeInfo);
-
-        typeNameIndex = fStringPool.addSymbol(typeName);
-        return typeNameIndex;
-
-
-    } // end of method: traverseComplexTypeDecl
-
-    private void checkRecursingComplexType() throws Exception {
-        if ( fCurrentTypeNameStack.empty() ) {
-            if (! fElementRecurseComplex.isEmpty() ) {
-                Enumeration e = fElementRecurseComplex.keys();
-                while( e.hasMoreElements() ) {
-                    QName nameThenScope = (QName) e.nextElement();
-                    String typeName = (String) fElementRecurseComplex.get(nameThenScope);
-
-                    int eltUriIndex = nameThenScope.uri;
-                    int eltNameIndex = nameThenScope.localpart;
-                    int enclosingScope = nameThenScope.prefix;
-                    ComplexTypeInfo typeInfo = 
-                        (ComplexTypeInfo) fComplexTypeRegistry.get(fTargetNSURIString+","+typeName);
-                    if (typeInfo==null) {
-                        throw new Exception ( "Internal Error in void checkRecursingComplexType(). " );
-                    }
-                    else {
-                        int elementIndex = fSchemaGrammar.addElementDecl(new QName(-1, eltNameIndex, eltNameIndex, eltUriIndex), 
-                                                                         enclosingScope, typeInfo.scopeDefined, 
-                                                                         typeInfo.contentType, 
-                                                                         typeInfo.contentSpecHandle, 
-                                                                         typeInfo.attlistHead, 
-                                                                         typeInfo.datatypeValidator);
-                        fSchemaGrammar.setElementComplexTypeInfo(elementIndex, typeInfo);
-                    }
-
-                }
-                fElementRecurseComplex.clear();
-            }
-        }
-    }
-
-    private void checkParticleDerivationOK(Element derivedTypeNode, Element baseTypeNode) {
-        //TO DO: !!!
-    }
-
-    private int expandContentModel ( int index, Element particle) throws Exception {
-        
-        String minOccurs = particle.getAttribute(SchemaSymbols.ATT_MINOCCURS).trim();
-        String maxOccurs = particle.getAttribute(SchemaSymbols.ATT_MAXOCCURS).trim();    
-
-        int min=1, max=1;
-
-        if(minOccurs.equals("0") && maxOccurs.equals("0")){
-            return -2;
-        }
-
-        if (minOccurs.equals("")) {
-            minOccurs = "1";
-        }
-        if (maxOccurs.equals("") ){
-            if ( minOccurs.equals("0")) {
-                maxOccurs = "1";
-            }
-            else {
-                maxOccurs = minOccurs;
-            }
-        }
-
-
-        int leafIndex = index;
-        //REVISIT: !!! minoccurs, maxoccurs.
-        if (minOccurs.equals("1")&& maxOccurs.equals("1")) {
-
-        }
-        else if (minOccurs.equals("0")&& maxOccurs.equals("1")) {
-            //zero or one
-            index = fSchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE,
-                                                   index,
-                                                   -1,
-                                                   false);
-        }
-        else if (minOccurs.equals("0")&& maxOccurs.equals("unbounded")) {
-            //zero or more
-            index = fSchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE,
-                                                   index,
-                                                   -1,
-                                                   false);
-        }
-        else if (minOccurs.equals("1")&& maxOccurs.equals("unbounded")) {
-            //one or more
-            index = fSchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE,
-                                                   index,
-                                                   -1,
-                                                   false);
-        }
-        else if (maxOccurs.equals("unbounded") ) {
-            // >=2 or more
-            try {
-                min = Integer.parseInt(minOccurs);
-            }
-            catch (Exception e) {
-                reportSchemaError(SchemaMessageProvider.GenericError,
-                                  new Object [] { "illegal value for minOccurs : '" +e.getMessage()+ "' " });
-            }
-            if (min<2) {
-                //REVISIT: report Error here
-            }
-
-            // => a,a,..,a+
-            index = fSchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE,
-                   index,
-                   -1,
-                   false);
-
-            for (int i=0; i < (min-1); i++) {
-                index = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
-                                                      leafIndex,
-                                                      index,
-                                                      false);
-            }
-
-        }
-        else {
-            // {n,m} => a,a,a,...(a),(a),...
-            try {
-                min = Integer.parseInt(minOccurs);
-                max = Integer.parseInt(maxOccurs);
-            }
-            catch (Exception e){
-                reportSchemaError(SchemaMessageProvider.GenericError,
-                                  new Object [] { "illegal value for minOccurs or maxOccurs : '" +e.getMessage()+ "' "});
-            }
-            if (min==0) {
-                int optional = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE,
-                                                                 leafIndex,
-                                                                 -1,
-                                                                 false);
-                index = optional;
-                for (int i=0; i < (max-min-1); i++) {
-                    index = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
-                                                              index,
-                                                              optional,
-                                                              false);
-                }
-            }
-            else {
-                for (int i=0; i<(min-1); i++) {
-                    index = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
-                                                          index,
-                                                          leafIndex,
-                                                          false);
-                }
-
-                int optional = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE,
-                                                                 leafIndex,
-                                                                 -1,
-                                                                 false);
-                for (int i=0; i < (max-min); i++) {
-                    index = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
-                                                              index,
-                                                              optional,
-                                                              false);
-                }
-            }
-        }
-
-        return index;
-    }
-
-    /**
-     * Traverses Schema attribute declaration.
-     *   
-     *       <attribute 
-     *         form = qualified | unqualified 
-     *         id = ID 
-     *         name = NCName 
-     *         ref = QName 
-     *         type = QName 
-     *         use = default | fixed | optional | prohibited | required 
-     *         value = string>
-     *         Content: (annotation? , simpleType?)
-     *       <attribute/>
-     * 
-     * @param attributeDecl
-     * @return 
-     * @exception Exception
-     */
-    private int traverseAttributeDecl( Element attrDecl, ComplexTypeInfo typeInfo ) throws Exception {
-        String attNameStr    = attrDecl.getAttribute(SchemaSymbols.ATT_NAME);
-        int attName          = fStringPool.addSymbol(attNameStr);// attribute name
-        String isQName       = attrDecl.getAttribute(SchemaSymbols.ATT_FORM);//form attribute
-
-        DatatypeValidator dv = null;
-        // attribute type
-        int attType          = -1;
-        boolean attIsList    = false;
-        int dataTypeSymbol   = -1;
-
-        String ref       = attrDecl.getAttribute(SchemaSymbols.ATT_REF); 
-        String datatype  = attrDecl.getAttribute(SchemaSymbols.ATT_TYPE);
-        String localpart = null;
-
-        if (!ref.equals("")) {
-            if (XUtil.getFirstChildElement(attrDecl) != null)
-                reportSchemaError(SchemaMessageProvider.NoContentForRef, null);
-            String prefix = "";
-            localpart = ref;
-            int colonptr = ref.indexOf(":");
-            if ( colonptr > 0) {
-                prefix = ref.substring(0,colonptr);
-                localpart = ref.substring(colonptr+1);
-            }
-            String uriStr = resolvePrefixToURI(prefix);
-
-            if (!uriStr.equals(fTargetNSURIString)) {
-                addAttributeDeclFromAnotherSchema(localpart, uriStr, typeInfo);
-
-                return -1;
-                // TO DO
-                // REVISIT: different NS, not supported yet.
-                // REVISIT: Localize
-                //reportGenericSchemaError("Feature not supported: see an attribute from different NS");
-            }
-
-            Element referredAttribute = getTopLevelComponentByName(SchemaSymbols.ELT_ATTRIBUTE,localpart);
-            if (referredAttribute != null) {
-                traverseAttributeDecl(referredAttribute, typeInfo);
-            }
-            else {
-                // REVISIT: Localize
-                reportGenericSchemaError ( "Couldn't find top level attribute " + ref);
-            }
-            return -1;
-        }
-
-
-        if (datatype.equals("")) {
-            Element child = XUtil.getFirstChildElement(attrDecl);
-
-            while (child != null && 
-                             !child.getNodeName().equals(SchemaSymbols.ELT_SIMPLETYPE))
-                child = XUtil.getNextSiblingElement(child);
-
-
-            if (child != null && child.getNodeName().equals(SchemaSymbols.ELT_SIMPLETYPE)) {
-                attType        = XMLAttributeDecl.TYPE_SIMPLE;
-                dataTypeSymbol = traverseSimpleTypeDecl(child);
-                localpart = fStringPool.toString(dataTypeSymbol);
-            } 
-            else {
-                attType        = XMLAttributeDecl.TYPE_SIMPLE;
-                localpart      = "string";
-                dataTypeSymbol = fStringPool.addSymbol(localpart);
-            }
-            localpart = fStringPool.toString(dataTypeSymbol);
-
-            dv = fDatatypeRegistry.getDatatypeValidator(localpart);
-
-        } else {
-
-            String prefix = "";
-            localpart = datatype;
-            dataTypeSymbol = fStringPool.addSymbol(localpart);
-
-            int  colonptr = datatype.indexOf(":");
-            if ( colonptr > 0) {
-                prefix = datatype.substring(0,colonptr);
-                localpart = datatype.substring(colonptr+1);
-            }
-            String typeURI = resolvePrefixToURI(prefix);
-
-            if ( typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) 
-                 || typeURI.length()==0) {
-
-                dv = getDatatypeValidator("", localpart);
-
-                if (localpart.equals("ID")) {
-                    attType = XMLAttributeDecl.TYPE_ID;
-                } else if (localpart.equals("IDREF")) {
-                    attType = XMLAttributeDecl.TYPE_IDREF;
-                } else if (localpart.equals("IDREFS")) {
-                    attType = XMLAttributeDecl.TYPE_IDREF;
-                    attIsList = true;
-                } else if (localpart.equals("ENTITY")) {
-                    attType = XMLAttributeDecl.TYPE_ENTITY;
-                } else if (localpart.equals("ENTITIES")) {
-                    attType = XMLAttributeDecl.TYPE_ENTITY;
-                    attIsList = true;
-                } else if (localpart.equals("NMTOKEN")) {
-                    attType = XMLAttributeDecl.TYPE_NMTOKEN;
-                } else if (localpart.equals("NMTOKENS")) {
-                    attType = XMLAttributeDecl.TYPE_NMTOKEN;
-                    attIsList = true;
-                } else if (localpart.equals(SchemaSymbols.ELT_NOTATION)) {
-                    attType = XMLAttributeDecl.TYPE_NOTATION;
-                }
-                else {
-                    attType = XMLAttributeDecl.TYPE_SIMPLE;
-                    if (dv == null && typeURI.length() == 0) {
-                        Element topleveltype = getTopLevelComponentByName(SchemaSymbols.ELT_SIMPLETYPE, localpart);
-                        if (topleveltype != null) {
-                            traverseSimpleTypeDecl( topleveltype );
-                            dv = getDatatypeValidator(typeURI, localpart);
-                        }else {
-                            // REVISIT: Localize
-                            reportGenericSchemaError("simpleType not found : " + localpart);
-                        }
-                    }
-                }
-            } else {
-
-                // check if the type is from the same Schema
-
-                dv = getDatatypeValidator(typeURI, localpart);
-                if (dv == null && typeURI.equals(fTargetNSURIString) ) {
-                    Element topleveltype = getTopLevelComponentByName(SchemaSymbols.ELT_SIMPLETYPE, localpart);
-                    if (topleveltype != null) {
-                        traverseSimpleTypeDecl( topleveltype );
-                        dv = getDatatypeValidator(typeURI, localpart);
-                    }else {
-                        // REVISIT: Localize
-                        reportGenericSchemaError("simpleType not found : " + localpart);
-                    }
-                }
-
-                attType = XMLAttributeDecl.TYPE_SIMPLE;
-            }
-
-        }
-
-
-        // attribute default type
-        int attDefaultType = -1;
-        int attDefaultValue = -1;
-
-        String  use      = attrDecl.getAttribute(SchemaSymbols.ATT_USE);
-        boolean required = use.equals(SchemaSymbols.ATTVAL_REQUIRED);
-
-
-        if (dv == null) {
-            // REVISIT: Localize
-            reportGenericSchemaError("could not resolve the type or get a null validator for datatype : " 
-                                     + fStringPool.toString(dataTypeSymbol));
-        }
-
-        if (required) {
-            attDefaultType = XMLAttributeDecl.DEFAULT_TYPE_REQUIRED;
-        } else {
-            if (use.equals(SchemaSymbols.ATTVAL_FIXED)) {
-                String fixed = attrDecl.getAttribute(SchemaSymbols.ATT_VALUE);
-                if (!fixed.equals("")) {
-                    attDefaultType = XMLAttributeDecl.DEFAULT_TYPE_FIXED;
-                    attDefaultValue = fStringPool.addString(fixed);
-                } 
-            }
-            else if (use.equals(SchemaSymbols.ATTVAL_DEFAULT)) {
-                // attribute default value
-                String defaultValue = attrDecl.getAttribute(SchemaSymbols.ATT_VALUE);
-                if (!defaultValue.equals("")) {
-                    attDefaultType = XMLAttributeDecl.DEFAULT_TYPE_DEFAULT;
-                    attDefaultValue = fStringPool.addString(defaultValue);
-                } 
-            }
-            else if (use.equals(SchemaSymbols.ATTVAL_PROHIBITED)) {
-                
-                //REVISIT, TO DO. !!!
-                attDefaultType = XMLAttributeDecl.DEFAULT_TYPE_IMPLIED;
-                //attDefaultValue = fStringPool.addString("");
-            }
-            else {
-                attDefaultType = XMLAttributeDecl.DEFAULT_TYPE_IMPLIED;
-            }       // check default value is valid for the datatype.
-
-            if (attType == XMLAttributeDecl.TYPE_SIMPLE && attDefaultValue != -1) {
-                try { 
-                    if (dv != null) 
-                        //REVISIT
-                        dv.validate(fStringPool.toString(attDefaultValue), null);
-                    else
-                        reportSchemaError(SchemaMessageProvider.NoValidatorFor,
-                                          new Object [] { datatype });
-                } catch (InvalidDatatypeValueException idve) {
-                    reportSchemaError(SchemaMessageProvider.IncorrectDefaultType,
-                                      new Object [] { attrDecl.getAttribute(SchemaSymbols.ATT_NAME), idve.getMessage() });
-                } catch (Exception e) {
-                    e.printStackTrace();
-                    System.out.println("Internal error in attribute datatype validation");
-                }
-            }
-        }
-
-        int uriIndex = -1;
-        if ( isQName.equals(SchemaSymbols.ATTVAL_QUALIFIED)||
-             fAttributeDefaultQualified || isTopLevel(attrDecl) ) {
-            uriIndex = fTargetNSURI;
-        }
-
-        QName attQName = new QName(-1,attName,attName,uriIndex);
-        if ( DEBUGGING )
-            System.out.println(" the dataType Validator for " + fStringPool.toString(attName) + " is " + dv);
-
-        //put the top-levels in the attribute decl registry.
-        if (isTopLevel(attrDecl)) {
-            fTempAttributeDecl.datatypeValidator = dv;
-            fTempAttributeDecl.name.setValues(attQName);
-            fTempAttributeDecl.type = attType;
-            fTempAttributeDecl.defaultType = attDefaultType;
-            fTempAttributeDecl.list = attIsList;
-            if (attDefaultValue != -1 ) {
-                fTempAttributeDecl.defaultValue = new String(fStringPool.toString(attDefaultValue));
-            }
-            fAttributeDeclRegistry.put(attNameStr, new XMLAttributeDecl(fTempAttributeDecl));
-        }
-
-        // add attribute to attr decl pool in fSchemaGrammar, 
-        if (typeInfo != null) {
-            fSchemaGrammar.addAttDef( typeInfo.templateElementIndex, 
-                                      attQName, attType, 
-                                      dataTypeSymbol, attDefaultType, 
-                                      fStringPool.toString( attDefaultValue), dv, attIsList);
-        }
-        return -1;
-    } // end of method traverseAttribute
-
-    private int addAttributeDeclFromAnotherSchema( String name, String uriStr, ComplexTypeInfo typeInfo) throws Exception {
-        SchemaGrammar aGrammar = (SchemaGrammar) fGrammarResolver.getGrammar(uriStr);
-        if (uriStr == null || ! (aGrammar instanceof SchemaGrammar) ) {
-            // REVISIT: Localize
-            reportGenericSchemaError("!!Schema not found in #addAttributeDeclFromAnotherSchema, schema uri : " + uriStr);
-            return -1;
-        }
-
-        Hashtable attrRegistry = aGrammar.getAttirubteDeclRegistry();
-        if (attrRegistry == null) {
-            // REVISIT: Localize
-            reportGenericSchemaError("no attribute was defined in schema : " + uriStr);
-            return -1;
-        }
-
-        XMLAttributeDecl tempAttrDecl = (XMLAttributeDecl) attrRegistry.get(name);
-
-        if (tempAttrDecl == null) {
-            // REVISIT: Localize
-            reportGenericSchemaError( "no attribute named \"" + name 
-                                      + "\" was defined in schema : " + uriStr);
-            return -1;
-        }
-
-
-        if (typeInfo!= null) {
-            fSchemaGrammar.addAttDef( typeInfo.templateElementIndex, 
-                                      tempAttrDecl.name, tempAttrDecl.type,
-                                      -1, tempAttrDecl.defaultType,
-                                      tempAttrDecl.defaultValue, 
-                                      tempAttrDecl.datatypeValidator, 
-                                      tempAttrDecl.list);
-        }
-
-
-        return 0;
-    }
-
-    /*
-    * 
-    * <attributeGroup 
-    *   id = ID 
-    *   name = NCName
-    *   ref = QName>
-    *   Content: (annotation?, (attribute|attributeGroup), anyAttribute?)
-    * </>
-    * 
-    */
-    private int traverseAttributeGroupDecl( Element attrGrpDecl, ComplexTypeInfo typeInfo, Vector anyAttDecls ) throws Exception {
-        // attribute name
-        int attGrpName = fStringPool.addSymbol(attrGrpDecl.getAttribute(SchemaSymbols.ATT_NAME));
-        
-        String ref = attrGrpDecl.getAttribute(SchemaSymbols.ATT_REF); 
-
-        // attribute type
-        int attType = -1;
-        int enumeration = -1;
-
-        if (!ref.equals("")) {
-            if (XUtil.getFirstChildElement(attrGrpDecl) != null)
-                reportSchemaError(SchemaMessageProvider.NoContentForRef, null);
-            String prefix = "";
-            String localpart = ref;
-            int colonptr = ref.indexOf(":");
-            if ( colonptr > 0) {
-                prefix = ref.substring(0,colonptr);
-                localpart = ref.substring(colonptr+1);
-            }
-            String uriStr = resolvePrefixToURI(prefix);
-            if (!uriStr.equals(fTargetNSURIString)) {
-                
-                traverseAttributeGroupDeclFromAnotherSchema(localpart, uriStr, typeInfo, anyAttDecls);
-
-                return -1;
-                // TO DO 
-                // REVISIST: different NS, not supported yet.
-                // REVISIT: Localize
-                //reportGenericSchemaError("Feature not supported: see an attribute from different NS");
-            }
-            Element referredAttrGrp = getTopLevelComponentByName(SchemaSymbols.ELT_ATTRIBUTEGROUP,localpart);
-            if (referredAttrGrp != null) {
-                traverseAttributeGroupDecl(referredAttrGrp, typeInfo, anyAttDecls);
-            }
-            else {
-                // REVISIT: Localize
-                reportGenericSchemaError ( "Couldn't find top level attributegroup " + ref);
-            }
-            return -1;
-        }
-
-        for ( Element child = XUtil.getFirstChildElement(attrGrpDecl); 
-             child != null ; child = XUtil.getNextSiblingElement(child)) {
-       
-            if ( child.getNodeName().equals(SchemaSymbols.ELT_ATTRIBUTE) ){
-                traverseAttributeDecl(child, typeInfo);
-            }
-            else if ( child.getNodeName().equals(SchemaSymbols.ELT_ATTRIBUTEGROUP) ) {
-                traverseAttributeGroupDecl(child, typeInfo,anyAttDecls);
-            }
-            else if ( child.getNodeName().equals(SchemaSymbols.ELT_ANYATTRIBUTE) ) {
-                anyAttDecls.addElement(traverseAnyAttribute(child));
-                break;
-            }
-            else if (child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION) ) {
-                // REVISIT: what about appInfo
-            }
-        }
-        return -1;
-    } // end of method traverseAttributeGroup
-    
-    private int traverseAttributeGroupDeclFromAnotherSchema( String attGrpName , String uriStr, 
-                                                             ComplexTypeInfo typeInfo,
-                                                             Vector anyAttDecls ) throws Exception {
-        
-        SchemaGrammar aGrammar = (SchemaGrammar) fGrammarResolver.getGrammar(uriStr);
-        if (uriStr == null || aGrammar == null || ! (aGrammar instanceof SchemaGrammar) ) {
-            // REVISIT: Localize
-            reportGenericSchemaError("!!Schema not found in #traverseAttributeGroupDeclFromAnotherSchema, schema uri : " + uriStr);
-            return -1;
-        }
-        // attribute name
-        Element attGrpDecl = (Element) aGrammar.topLevelAttrGrpDecls.get((Object)attGrpName);
-        if (attGrpDecl == null) {
-            // REVISIT: Localize
-            reportGenericSchemaError( "no attribute group named \"" + attGrpName 
-                                      + "\" was defined in schema : " + uriStr);
-            return -1;
-        }
-        
-        NamespacesScope saveNSMapping = fNamespacesScope;
-        int saveTargetNSUri = fTargetNSURI;
-        fTargetNSURI = fStringPool.addSymbol(aGrammar.getTargetNamespaceURI());
-        fNamespacesScope = aGrammar.getNamespacesScope();
-
-        // attribute type
-        int attType = -1;
-        int enumeration = -1;
-
-
-        for ( Element child = XUtil.getFirstChildElement(attGrpDecl); 
-             child != null ; child = XUtil.getNextSiblingElement(child)) {
-
-            //child attribute couldn't be a top-level attribute DEFINITION, 
-            if ( child.getNodeName().equals(SchemaSymbols.ELT_ATTRIBUTE) ){
-                String childAttName = child.getAttribute(SchemaSymbols.ATT_NAME);
-                if ( childAttName.length() > 0 ) {
-                    Hashtable attDeclRegistry = aGrammar.getAttirubteDeclRegistry();
-                    if (attDeclRegistry != null) {
-                        if (attDeclRegistry.get((Object)childAttName) != null ){
-                            addAttributeDeclFromAnotherSchema(childAttName, uriStr, typeInfo);
-                            return -1;
-                        }
-                    }       
-                }
-                else 
-                    traverseAttributeDecl(child, typeInfo);
-            }
-            else if ( child.getNodeName().equals(SchemaSymbols.ELT_ATTRIBUTEGROUP) ) {
-                traverseAttributeGroupDecl(child, typeInfo, anyAttDecls);
-            }
-            else if ( child.getNodeName().equals(SchemaSymbols.ELT_ANYATTRIBUTE) ) {
-                anyAttDecls.addElement(traverseAnyAttribute(child));
-                break;
-            }
-            else if (child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION) ) {
-                // REVISIT: what about appInfo
-            }
-        }
-
-        fNamespacesScope = saveNSMapping;
-        fTargetNSURI = saveTargetNSUri;
-        return -1;
-    } // end of method traverseAttributeGroupFromAnotherSchema
-    
-
-    /**
-     * Traverse element declaration:
-     *  <element
-     *         abstract = boolean
-     *         block = #all or (possibly empty) subset of {equivClass, extension, restriction}
-     *         default = string
-     *         equivClass = QName
-     *         final = #all or (possibly empty) subset of {extension, restriction}
-     *         fixed = string
-     *         form = qualified | unqualified
-     *         id = ID
-     *         maxOccurs = string
-     *         minOccurs = nonNegativeInteger
-     *         name = NCName
-     *         nullable = boolean
-     *         ref = QName
-     *         type = QName>
-     *   Content: (annotation? , (simpleType | complexType)? , (unique | key | keyref)*)
-     *   </element>
-     * 
-     * 
-     *       The following are identity-constraint definitions
-     *        <unique 
-     *         id = ID 
-     *         name = NCName>
-     *         Content: (annotation? , (selector , field+))
-     *       </unique>
-     *       
-     *       <key 
-     *         id = ID 
-     *         name = NCName>
-     *         Content: (annotation? , (selector , field+))
-     *       </key>
-     *       
-     *       <keyref 
-     *         id = ID 
-     *         name = NCName 
-     *         refer = QName>
-     *         Content: (annotation? , (selector , field+))
-     *       </keyref>
-     *       
-     *       <selector>
-     *         Content: XPathExprApprox : An XPath expression 
-     *       </selector>
-     *       
-     *       <field>
-     *         Content: XPathExprApprox : An XPath expression 
-     *       </field>
-     *       
-     * 
-     * @param elementDecl
-     * @return 
-     * @exception Exception
-     */
-    private QName traverseElementDecl(Element elementDecl) throws Exception {
-
-        int contentSpecType      = -1;
-        int contentSpecNodeIndex = -1;
-        int typeNameIndex = -1;
-        int scopeDefined = -2; //signal a error if -2 gets gets through 
-                                //cause scope can never be -2.
-        DatatypeValidator dv = null;
-
-
-
-        String name = elementDecl.getAttribute(SchemaSymbols.ATT_NAME);
-
-        if ( DEBUGGING )
-            System.out.println("traversing element decl : " + name );
-
-        String ref = elementDecl.getAttribute(SchemaSymbols.ATT_REF);
-        String type = elementDecl.getAttribute(SchemaSymbols.ATT_TYPE);
-        String minOccurs = elementDecl.getAttribute(SchemaSymbols.ATT_MINOCCURS);
-        String maxOccurs = elementDecl.getAttribute(SchemaSymbols.ATT_MAXOCCURS);
-        String dflt = elementDecl.getAttribute(SchemaSymbols.ATT_DEFAULT);
-        String fixed = elementDecl.getAttribute(SchemaSymbols.ATT_FIXED);
-        String equivClass = elementDecl.getAttribute(SchemaSymbols.ATT_EQUIVCLASS);
-        // form attribute
-        String isQName = elementDecl.getAttribute(SchemaSymbols.ATT_FORM);
-
-        String fromAnotherSchema = null;
-
-        if (isTopLevel(elementDecl)) {
-        
-            int nameIndex = fStringPool.addSymbol(name);
-            int eltKey = fSchemaGrammar.getElementDeclIndex(fTargetNSURI, nameIndex,TOP_LEVEL_SCOPE);
-            if (eltKey > -1 ) {
-                return new QName(-1,nameIndex,nameIndex,fTargetNSURI);
-            }
-        }
-        
-        // parse out 'block', 'final', 'nullable', 'abstract'
-        int blockSet = parseBlockSet(elementDecl.getAttribute(SchemaSymbols.ATT_BLOCK));
-        int finalSet = parseFinalSet(elementDecl.getAttribute(SchemaSymbols.ATT_FINAL));
-        boolean isNullable = elementDecl.getAttribute
-            (SchemaSymbols.ATT_NULLABLE).equals(SchemaSymbols.ATTVAL_TRUE)? true:false;
-        boolean isAbstract = elementDecl.getAttribute
-            (SchemaSymbols.ATT_ABSTRACT).equals(SchemaSymbols.ATTVAL_TRUE)? true:false;
-        int elementMiscFlags = 0;
-        if (isNullable) {
-            elementMiscFlags += SchemaSymbols.NULLABLE;
-        }
-        if (isAbstract) {
-            elementMiscFlags += SchemaSymbols.ABSTRACT;
-        }
-
-        //if this is a reference to a global element
-        int attrCount = 0;
-        if (!ref.equals("")) attrCount++;
-        if (!type.equals("")) attrCount++;
-                //REVISIT top level check for ref & archref
-        if (attrCount > 1)
-            reportSchemaError(SchemaMessageProvider.OneOfTypeRefArchRef, null);
-
-        if (!ref.equals("")) {
-            if (XUtil.getFirstChildElement(elementDecl) != null)
-                reportSchemaError(SchemaMessageProvider.NoContentForRef, null);
-            String prefix = "";
-            String localpart = ref;
-            int colonptr = ref.indexOf(":");
-            if ( colonptr > 0) {
-                prefix = ref.substring(0,colonptr);
-                localpart = ref.substring(colonptr+1);
-            }
-            int localpartIndex = fStringPool.addSymbol(localpart);
-            String uriString = resolvePrefixToURI(prefix);
-            QName eltName = new QName(prefix != null ? fStringPool.addSymbol(prefix) : -1,
-                                      localpartIndex,
-                                      fStringPool.addSymbol(ref),
-                                      uriString != null ? fStringPool.addSymbol(uriString) : -1);
-
-            //if from another schema, just return the element QName
-            if (! uriString.equals(fTargetNSURIString) ) {
-                return eltName;
-            }
-
-            int elementIndex = fSchemaGrammar.getElementDeclIndex(eltName, TOP_LEVEL_SCOPE);
-            //if not found, traverse the top level element that if referenced
-
-            if (elementIndex == -1 ) {
-                Element targetElement = getTopLevelComponentByName(SchemaSymbols.ELT_ELEMENT,localpart);
-                if (targetElement == null ) {
-                    // REVISIT: Localize
-                    reportGenericSchemaError("Element " + localpart + " not found in the Schema");
-                    //REVISIT, for now, the QName anyway
-                    return eltName;
-                    //return new QName(-1,fStringPool.addSymbol(localpart), -1, fStringPool.addSymbol(uriString));
-                }
-                else {
-                    // do nothing here, other wise would cause infinite loop for 
-                    //   <element name="recur"><complexType><element ref="recur"> ...
-                    //eltName= traverseElementDecl(targetElement);
-                }
-            }
-            return eltName;
-        }
-                
-        // Handle the equivClass
-        Element equivClassElementDecl = null;
-        int equivClassElementDeclIndex = -1;
-        boolean noErrorSoFar = true;
-        String equivClassUri = null;
-        String equivClassLocalpart = null;
-        String equivClassFullName = null;
-        ComplexTypeInfo equivClassEltTypeInfo = null;
-        DatatypeValidator equivClassEltDV = null;
-
-        if ( equivClass.length() > 0 ) {
-            equivClassUri =  resolvePrefixToURI(getPrefix(equivClass));
-            equivClassLocalpart = getLocalPart(equivClass);
-            equivClassFullName = equivClassUri+","+equivClassLocalpart;
-           
-            if ( !equivClassUri.equals(fTargetNSURIString) ) {  
-                equivClassEltTypeInfo = getElementDeclTypeInfoFromNS(equivClassUri, equivClassLocalpart);
-                if (equivClassEltTypeInfo == null) {
-                    equivClassEltDV = getElementDeclTypeValidatorFromNS(equivClassUri, equivClassLocalpart);
-                    if (equivClassEltDV == null) {
-                        //TO DO: report error here;
-                        noErrorSoFar = false;
-                        reportGenericSchemaError("Could not find type for element '" +equivClassLocalpart 
-                                                 + "' in schema '" + equivClassUri+"'");
-                    }
-                }
-            }
-            else {
-                equivClassElementDecl = getTopLevelComponentByName(SchemaSymbols.ELT_ELEMENT, equivClassLocalpart);
-                if (equivClassElementDecl == null) {
-                    equivClassElementDeclIndex = 
-                        fSchemaGrammar.getElementDeclIndex(fTargetNSURI, getLocalPartIndex(equivClass),TOP_LEVEL_SCOPE);
-                    if ( equivClassElementDeclIndex == -1) {
-                        noErrorSoFar = false;
-                        // REVISIT: Localize
-                        reportGenericSchemaError("Equivclass affiliation element "
-                                                  +equivClass
-                                                  +" in element declaration " 
-                                                  +name);  
-                    }
-                }
-                else {
-                    equivClassElementDeclIndex = 
-                        fSchemaGrammar.getElementDeclIndex(fTargetNSURI, getLocalPartIndex(equivClass),TOP_LEVEL_SCOPE);
-
-                    if ( equivClassElementDeclIndex == -1) {
-                        traverseElementDecl(equivClassElementDecl);
-                        equivClassElementDeclIndex = 
-                            fSchemaGrammar.getElementDeclIndex(fTargetNSURI, getLocalPartIndex(equivClass),TOP_LEVEL_SCOPE);
-                    }
-                }
-
-                if (equivClassElementDeclIndex != -1) {
-                    equivClassEltTypeInfo = fSchemaGrammar.getElementComplexTypeInfo( equivClassElementDeclIndex );
-                    if (equivClassEltTypeInfo == null) {
-                        fSchemaGrammar.getElementDecl(equivClassElementDeclIndex, fTempElementDecl);
-                        equivClassEltDV = fTempElementDecl.datatypeValidator;
-                        if (equivClassEltDV == null) {
-                            //TO DO: report error here;
-                            noErrorSoFar = false;
-                            reportGenericSchemaError("Could not find type for element '" +equivClassLocalpart 
-                                                     + "' in schema '" + equivClassUri+"'");
-                        }
-                    }
-                }
-            }
- 
-        }
-        
-
-        //
-        // resolving the type for this element right here
-        //
-
-        ComplexTypeInfo typeInfo = null;
-
-        // element has a single child element, either a datatype or a type, null if primitive
-        Element child = XUtil.getFirstChildElement(elementDecl);
-        
-        while (child != null && child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION))
-            child = XUtil.getNextSiblingElement(child);
-        
-        boolean haveAnonType = false;
-
-        // Handle Anonymous type if there is one
-        if (child != null) {
-            
-            String childName = child.getNodeName();
-            
-            if (childName.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
-                if (child.getAttribute(SchemaSymbols.ATT_NAME).length() > 0) {
-                    noErrorSoFar = false;
-                    // REVISIT: Localize
-                    reportGenericSchemaError("anonymous complexType in element '" + name +"' has a name attribute"); 
-                }
-                else 
-                    typeNameIndex = traverseComplexTypeDecl(child);
-                if (typeNameIndex != -1 ) {
-                    typeInfo = (ComplexTypeInfo)
-                        fComplexTypeRegistry.get(fStringPool.toString(typeNameIndex));
-                }
-                else {
-                    noErrorSoFar = false;
-                    // REVISIT: Localize
-                    reportGenericSchemaError("traverse complexType error in element '" + name +"'"); 
-                }
-                haveAnonType = true;
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
-                //   TO DO:  the Default and fixed attribute handling should be here.                
-                if (child.getAttribute(SchemaSymbols.ATT_NAME).length() > 0) {
-                    noErrorSoFar = false;
-                    // REVISIT: Localize
-                    reportGenericSchemaError("anonymous simpleType in element '" + name +"' has a name attribute"); 
-                }
-                else 
-                    typeNameIndex = traverseSimpleTypeDecl(child);
-                if (typeNameIndex != -1) {
-                    dv = fDatatypeRegistry.getDatatypeValidator(fStringPool.toString(typeNameIndex));
-                }
-                else {
-                    noErrorSoFar = false;
-                    // REVISIT: Localize
-                    reportGenericSchemaError("traverse simpleType error in element '" + name +"'"); 
-                }
-                contentSpecType = XMLElementDecl.TYPE_SIMPLE; 
-                haveAnonType = true;
-            } else if (type.equals("")) { // "ur-typed" leaf
-                contentSpecType = XMLElementDecl.TYPE_ANY;
-                    //REVISIT: is this right?
-                //contentSpecType = fStringPool.addSymbol("UR_TYPE");
-                // set occurrence count
-                contentSpecNodeIndex = -1;
-            } else {
-                System.out.println("unhandled case in TraverseElementDecl");
-            }
-        } 
-
-        // handle type="" here
-        if (haveAnonType && (type.length()>0)) {
-            noErrorSoFar = false;
-            // REVISIT: Localize
-            reportGenericSchemaError( "Element '"+ name +
-                                      "' have both a type attribute and a annoymous type child" );
-        }
-        // type specified as an attribute and no child is type decl.
-        else if (!type.equals("")) { 
-            if (equivClassElementDecl != null) {
-                checkEquivClassOK(elementDecl, equivClassElementDecl); 
-            }
-            String prefix = "";
-            String localpart = type;
-            int colonptr = type.indexOf(":");
-            if ( colonptr > 0) {
-                prefix = type.substring(0,colonptr);
-                localpart = type.substring(colonptr+1);
-            }
-            String typeURI = resolvePrefixToURI(prefix);
-            
-            // check if the type is from the same Schema
-            if ( !typeURI.equals(fTargetNSURIString) 
-                 && !typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
-                 && typeURI.length() != 0) {  // REVISIT, only needed because of resolvePrifixToURI.
-                fromAnotherSchema = typeURI;
-                typeInfo = getTypeInfoFromNS(typeURI, localpart);
-                if (typeInfo == null) {
-                    dv = getTypeValidatorFromNS(typeURI, localpart);
-                    if (dv == null) {
-                        //TO DO: report error here;
-                        noErrorSoFar = false;
-                        reportGenericSchemaError("Could not find type " +localpart 
-                                           + " in schema " + typeURI);
-                    }
-                }
-            }
-            else {
-                typeInfo = (ComplexTypeInfo) fComplexTypeRegistry.get(typeURI+","+localpart);
-                if (typeInfo == null) {
-                    dv = getDatatypeValidator(typeURI, localpart);
-                    if (dv == null )
-                    if (typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
-                        && !fTargetNSURIString.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) 
-                    {
-                        noErrorSoFar = false;
-                        // REVISIT: Localize
-                        reportGenericSchemaError("type not found : " + typeURI+":"+localpart);
-                    }
-                    else {
-                        Element topleveltype = getTopLevelComponentByName(SchemaSymbols.ELT_COMPLEXTYPE,localpart);
-                        if (topleveltype != null) {
-                            if (fCurrentTypeNameStack.search((Object)localpart) > - 1) {
-                                //then we found a recursive element using complexType.
-                                // REVISIT: this will be broken when recursing happens between 2 schemas
-                                int uriInd = -1;
-                                if ( isQName.equals(SchemaSymbols.ATTVAL_QUALIFIED)||
-                                     fElementDefaultQualified) {
-                                    uriInd = fTargetNSURI;
-                                }
-                                int nameIndex = fStringPool.addSymbol(name);
-                                QName tempQName = new QName(fCurrentScope, nameIndex, nameIndex, uriInd);
-                                fElementRecurseComplex.put(tempQName, localpart);
-                                return new QName(-1, nameIndex, nameIndex, uriInd);
-                            }
-                            else {
-                                typeNameIndex = traverseComplexTypeDecl( topleveltype );
-                                typeInfo = (ComplexTypeInfo)
-                                    fComplexTypeRegistry.get(fStringPool.toString(typeNameIndex));
-                            }
-                        }
-                        else {
-                            topleveltype = getTopLevelComponentByName(SchemaSymbols.ELT_SIMPLETYPE, localpart);
-                            if (topleveltype != null) {
-                                typeNameIndex = traverseSimpleTypeDecl( topleveltype );
-                                dv = getDatatypeValidator(typeURI, localpart);
-                                //   TO DO:  the Default and fixed attribute handling should be here.
-                            }
-                            else {
-                                noErrorSoFar = false;
-                                // REVISIT: Localize
-                                reportGenericSchemaError("type not found : " + typeURI+":"+localpart);
-                            }
-
-                        }
-
-                    }
-                }
-            }
-   
-        } 
-        else if (haveAnonType){
-            if (equivClassElementDecl != null ) {
-                checkEquivClassOK(elementDecl, equivClassElementDecl); 
-            }
-
-        }
-        // this element is ur-type, check its equivClass afficliation.
-        else {
-            // if there is equivClass affiliation and not type defintion found for this element, 
-            // then grab equivClass affiliation's type and give it to this element
-            if ( typeInfo == null && dv == null ) typeInfo = equivClassEltTypeInfo;
-            if ( typeInfo == null && dv == null ) dv = equivClassEltDV;
-        }
-
-        if (typeInfo == null && dv==null) {
-            if (noErrorSoFar) {
-                // Actually this Element's type definition is ur-type;
-                contentSpecType = XMLElementDecl.TYPE_ANY;
-                // REVISIT, need to wait till we have wildcards implementation.
-                // ADD attribute wildcards here
-            }
-            else {
-                noErrorSoFar = false;
-                // REVISIT: Localize
-                reportGenericSchemaError ("untyped element : " + name );
-            }
-        }
-        // if element belongs to a compelx type
-        if (typeInfo!=null) {
-            contentSpecNodeIndex = typeInfo.contentSpecHandle;
-            contentSpecType = typeInfo.contentType;
-            scopeDefined = typeInfo.scopeDefined;
-            dv = typeInfo.datatypeValidator;
-        }
-
-        // if element belongs to a simple type
-        if (dv!=null) {
-            contentSpecType = XMLElementDecl.TYPE_SIMPLE;
-            if (typeInfo == null) {
-                fromAnotherSchema = null; // not to switch schema in this case
-            }
-        }
-
-        //
-        // key/keyref/unique processing\
-        //
-
-        child = XUtil.getFirstChildElement(elementDecl);
-        Vector idConstraints = null;
-        
-        while (child != null){
-            String childName = child.getNodeName();
-           /**** 
-            if ( childName.equals(SchemaSymbols.ELT_KEY) ) { 
-                traverseKey(child, idCnstrt);
-            }
-            else if ( childName.equals(SchemaSymbols.ELT_KEYREF) ) {
-                traverseKeyRef(child, idCnstrt);
-            }
-            else if ( childName.equals(SchemaSymbols.ELT_UNIQUE) ) {
-                traverseUnique(child, idCnstrt);
-            }
-
-            if (idCnstrt!= null) {
-                if (idConstraints != null) {
-                    idConstraints = new Vector();
-                }
-                idConstraints.addElement(idCnstrt);
-            }
-            /****/
-            child = XUtil.getNextSiblingElement(child);
-        }
-        
-        //
-        // Create element decl
-        //
-
-        int elementNameIndex     = fStringPool.addSymbol(name);
-        int localpartIndex = elementNameIndex;
-        int uriIndex = -1;
-        int enclosingScope = fCurrentScope;
-
-        if ( isQName.equals(SchemaSymbols.ATTVAL_QUALIFIED)||
-             fElementDefaultQualified ) {
-            uriIndex = fTargetNSURI;
-        }
-
-        if ( isTopLevel(elementDecl)) {
-            uriIndex = fTargetNSURI;
-            enclosingScope = TOP_LEVEL_SCOPE;
-        }
-
-
-        //There can never be two elements with the same name and different type in the same scope.
-        int existSuchElementIndex = fSchemaGrammar.getElementDeclIndex(uriIndex, localpartIndex, enclosingScope);
-        if ( existSuchElementIndex > -1) {
-            fSchemaGrammar.getElementDecl(existSuchElementIndex, fTempElementDecl);
-            DatatypeValidator edv = fTempElementDecl.datatypeValidator;
-            ComplexTypeInfo eTypeInfo = fSchemaGrammar.getElementComplexTypeInfo(existSuchElementIndex);
-            if ( ((eTypeInfo != null)&&(eTypeInfo!=typeInfo))
-                 || ((edv != null)&&(edv != dv)) )  {
-                noErrorSoFar = false;
-                // REVISIT: Localize
-                reportGenericSchemaError("duplicate element decl in the same scope : " + 
-                                         fStringPool.toString(localpartIndex));
-
-            }
-        }
-
-        QName eltQName = new QName(-1,localpartIndex,elementNameIndex,uriIndex);
-        
-        // add element decl to pool
-        
-        int attrListHead = -1 ;
-
-        // copy up attribute decls from type object
-        if (typeInfo != null) {
-            attrListHead = typeInfo.attlistHead;
-        }
-        int elementIndex = fSchemaGrammar.addElementDecl(eltQName, enclosingScope, scopeDefined, 
-                                                         contentSpecType, contentSpecNodeIndex, 
-                                                         attrListHead, dv);
-        if ( DEBUGGING ) {
-            /***/
-            System.out.println("########elementIndex:"+elementIndex+" ("+fStringPool.toString(eltQName.uri)+","
-                               + fStringPool.toString(eltQName.localpart) + ")"+
-                               " eltType:"+type+" contentSpecType:"+contentSpecType+
-                               " SpecNodeIndex:"+ contentSpecNodeIndex +" enclosingScope: " +enclosingScope +
-                               " scopeDefined: " +scopeDefined+"\n");
-             /***/
-        }
-
-        if (typeInfo != null) {
-            fSchemaGrammar.setElementComplexTypeInfo(elementIndex, typeInfo);
-        }
-        else {
-            fSchemaGrammar.setElementComplexTypeInfo(elementIndex, typeInfo);
-
-            // REVISIT: should we report error from here?
-        }
-
-        // mark element if its type belongs to different Schema.
-        fSchemaGrammar.setElementFromAnotherSchemaURI(elementIndex, fromAnotherSchema);
-
-        // set BlockSet, FinalSet, Nullable and Abstract for this element decl
-        fSchemaGrammar.setElementDeclBlockSet(elementIndex, blockSet);
-        fSchemaGrammar.setElementDeclFinalSet(elementIndex, finalSet);
-        fSchemaGrammar.setElementDeclMiscFlags(elementIndex, elementMiscFlags);
-
-        // setEquivClassElementFullName
-        fSchemaGrammar.setElementDeclEquivClassElementFullName(elementIndex, equivClassFullName);
-
-        return eltQName;
-
-    }// end of method traverseElementDecl(Element)
-
-
-    int getLocalPartIndex(String fullName){
-        int colonAt = fullName.indexOf(":"); 
-        String localpart = fullName;
-        if (  colonAt > -1 ) {
-            localpart = fullName.substring(colonAt+1);
-        }
-        return fStringPool.addSymbol(localpart);
-    }
-    
-    String getLocalPart(String fullName){
-        int colonAt = fullName.indexOf(":"); 
-        String localpart = fullName;
-        if (  colonAt > -1 ) {
-            localpart = fullName.substring(colonAt+1);
-        }
-        return localpart;
-    }
-    
-    int getPrefixIndex(String fullName){
-        int colonAt = fullName.indexOf(":"); 
-        String prefix = "";
-        if (  colonAt > -1 ) {
-            prefix = fullName.substring(0,colonAt);
-        }
-        return fStringPool.addSymbol(prefix);
-    }
-
-    String getPrefix(String fullName){
-        int colonAt = fullName.indexOf(":"); 
-        String prefix = "";
-        if (  colonAt > -1 ) {
-            prefix = fullName.substring(0,colonAt);
-        }
-        return prefix;
-    }
-    
-    private void checkEquivClassOK(Element elementDecl, Element equivClassElementDecl){
-        //TO DO!!
-    }
-    
-    private Element getTopLevelComponentByName(String componentCategory, String name) throws Exception {
-        Element child = XUtil.getFirstChildElement(fSchemaRootElement);
-
-        if (child == null) {
-            return null;
-        }
-
-        while (child != null ){
-            if ( child.getNodeName().equals(componentCategory)) {
-                if (child.getAttribute(SchemaSymbols.ATT_NAME).equals(name)) {
-                    return child;
-                }
-            }
-            child = XUtil.getNextSiblingElement(child);
-        }
-
-        return null;
-    }
-
-    private boolean isTopLevel(Element component) {
-        //REVISIT, is this the right way to check ?
-        /****
-        if (component.getParentNode() == fSchemaRootElement ) {
-            return true;
-        }
-        /****/
-        if (component.getParentNode().getNodeName().endsWith(SchemaSymbols.ELT_SCHEMA) ) {
-            return true;
-        }
-        return false;
-    }
-    
-    DatatypeValidator getTypeValidatorFromNS(String newSchemaURI, String localpart) throws Exception {
-        // The following impl is for the case where every Schema Grammar has its own instance of DatatypeRegistry.
-        // Now that we have only one DataTypeRegistry used by all schemas. this is not needed.
-        /*****
-        Grammar grammar = fGrammarResolver.getGrammar(newSchemaURI);
-        if (grammar != null && grammar instanceof SchemaGrammar) {
-            SchemaGrammar sGrammar = (SchemaGrammar) grammar;
-            DatatypeValidator dv = (DatatypeValidator) fSchemaGrammar.getDatatypeRegistry().getDatatypeValidator(localpart);
-            return dv;
-        }
-        else {
-            reportGenericSchemaError("could not resolve URI : " + newSchemaURI + " to a SchemaGrammar in getTypeValidatorFromNS");
-        }
-        return null;
-        /*****/
-        return getDatatypeValidator(newSchemaURI, localpart);
-    }
-
-    ComplexTypeInfo getTypeInfoFromNS(String newSchemaURI, String localpart) throws Exception {
-        Grammar grammar = fGrammarResolver.getGrammar(newSchemaURI);
-        if (grammar != null && grammar instanceof SchemaGrammar) {
-            SchemaGrammar sGrammar = (SchemaGrammar) grammar;
-            ComplexTypeInfo typeInfo = (ComplexTypeInfo) sGrammar.getComplexTypeRegistry().get(newSchemaURI+","+localpart);
-            return typeInfo;
-        }
-        else {
-            reportGenericSchemaError("could not resolve URI : " + newSchemaURI + " to a SchemaGrammar in getTypeInfoFromNS");
-        }
-        return null;
-    }
-    
-    DatatypeValidator getElementDeclTypeValidatorFromNS(String newSchemaURI, String localpart) throws Exception {
-        Grammar grammar = fGrammarResolver.getGrammar(newSchemaURI);
-        if (grammar != null && grammar instanceof SchemaGrammar) {
-            SchemaGrammar sGrammar = (SchemaGrammar) grammar;
-            int eltIndex = sGrammar.getElementDeclIndex(fStringPool.addSymbol(newSchemaURI), 
-                                                        fStringPool.addSymbol(localpart), 
-                                                        TOP_LEVEL_SCOPE);
-
-            DatatypeValidator dv = null;
-            if (eltIndex>-1) {
-                sGrammar.getElementDecl(eltIndex, fTempElementDecl);
-                dv = fTempElementDecl.datatypeValidator;
-            }
-            else {
-                reportGenericSchemaError("could not find global element : '" + localpart 
-                                         + " in the SchemaGrammar "+newSchemaURI);
-            }
-            return dv;
-        }
-        else {
-            reportGenericSchemaError("could not resolve URI : " + newSchemaURI
-                                      + " to a SchemaGrammar in getELementDeclTypeValidatorFromNS");
-        }
-        return null;
-    }
-
-    ComplexTypeInfo getElementDeclTypeInfoFromNS(String newSchemaURI, String localpart) throws Exception {
-        Grammar grammar = fGrammarResolver.getGrammar(newSchemaURI);
-        if (grammar != null && grammar instanceof SchemaGrammar) {
-            SchemaGrammar sGrammar = (SchemaGrammar) grammar;
-            int eltIndex = sGrammar.getElementDeclIndex(fStringPool.addSymbol(newSchemaURI), 
-                                                              fStringPool.addSymbol(localpart), 
-                                                              TOP_LEVEL_SCOPE);
-            ComplexTypeInfo typeInfo = null;
-            if (eltIndex>-1) {
-                 typeInfo = sGrammar.getElementComplexTypeInfo(eltIndex);
-            }
-            else {
-                reportGenericSchemaError("could not find global element : '" + localpart 
-                                         + " in the SchemaGrammar "+newSchemaURI);
-
-            }
-            return typeInfo;
-        }
-        else {
-            reportGenericSchemaError("could not resolve URI : " + newSchemaURI 
-                                     + " to a SchemaGrammar in getElementDeclTypeInfoFromNS");
-        }
-        return null;
-    }
-
-    /**
-     * Traverse attributeGroup Declaration
-     * 
-     *   <attributeGroup
-     *         id = ID
-     *         ref = QName>
-     *         Content: (annotation?)
-     *      </>
-     * 
-     * @param elementDecl
-     * @exception Exception
-     */
-    /*private int traverseAttributeGroupDecl( Element attributeGroupDecl ) throws Exception {
-        int attributeGroupID         =  fStringPool.addSymbol(
-                                                             attributeGroupDecl.getAttribute( SchemaSymbols.ATTVAL_ID ));
-
-        int attributeGroupName      =  fStringPool.addSymbol(
-                                                            attributeGroupDecl.getAttribute( SchemaSymbols.ATT_NAME ));
-
-        return -1;
-    }*/
-
-
-    /**
-     * Traverse Group Declaration.
-     * 
-     * <group 
-     *         id = ID 
-     *         maxOccurs = string 
-     *         minOccurs = nonNegativeInteger 
-     *         name = NCName 
-     *         ref = QName>
-     *   Content: (annotation? , (element | group | all | choice | sequence | any)*)
-     * <group/>
-     * 
-     * @param elementDecl
-     * @return 
-     * @exception Exception
-     */
-    private int traverseGroupDecl( Element groupDecl ) throws Exception {
-
-        String groupName = groupDecl.getAttribute(SchemaSymbols.ATT_NAME);
-        String ref = groupDecl.getAttribute(SchemaSymbols.ATT_REF);
-
-        if (!ref.equals("")) {
-            if (XUtil.getFirstChildElement(groupDecl) != null)
-                reportSchemaError(SchemaMessageProvider.NoContentForRef, null);
-            String prefix = "";
-            String localpart = ref;
-            int colonptr = ref.indexOf(":");
-            if ( colonptr > 0) {
-                prefix = ref.substring(0,colonptr);
-                localpart = ref.substring(colonptr+1);
-            }
-            int localpartIndex = fStringPool.addSymbol(localpart);
-            
-            String uriStr = resolvePrefixToURI(prefix);
-
-            if (!uriStr.equals(fTargetNSURIString)) {
-                return traverseGroupDeclFromAnotherSchema(localpart, uriStr);
-            }
-
-            int contentSpecIndex = -1;
-            Element referredGroup = getTopLevelComponentByName(SchemaSymbols.ELT_GROUP,localpart);
-            if (referredGroup == null) {
-                // REVISIT: Localize
-                reportGenericSchemaError("Group " + localpart + " not found in the Schema");
-                //REVISIT, this should be some custom Exception
-                throw new Exception("Group " + localpart + " not found in the Schema");
-            }
-            else {
-                contentSpecIndex = traverseGroupDecl(referredGroup);
-            }
-            
-            return contentSpecIndex;
-        }
-
-        boolean traverseElt = true; 
-        if (fCurrentScope == TOP_LEVEL_SCOPE) {
-            traverseElt = false;
-        }
-
-        Element child = XUtil.getFirstChildElement(groupDecl);
-        while (child != null && child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION))
-            child = XUtil.getNextSiblingElement(child);
-
-        int contentSpecType = 0;
-        int csnType = 0;
-        int allChildren[] = null;
-        int allChildCount = 0;
-
-        csnType = XMLContentSpec.CONTENTSPECNODE_SEQ;
-        contentSpecType = XMLElementDecl.TYPE_CHILDREN;
-        
-        int left = -2;
-        int right = -2;
-        boolean hadContent = false;
-        boolean seeAll = false;
-        boolean seeParticle = false;
-
-        for (;
-             child != null;
-             child = XUtil.getNextSiblingElement(child)) {
-            int index = -2;
-            hadContent = true;
-
-            boolean illegalChild = false;
-
-            String childName = child.getNodeName();
-            if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
-                QName eltQName = traverseElementDecl(child);
-                index = fSchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_LEAF,
-                                                       eltQName.localpart,
-                                                       eltQName.uri, 
-                                                       false);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
-                index = traverseGroupDecl(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_ALL)) {
-                index = traverseAll(child);
-                //seeParticle = true;
-                seeAll = true;
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
-                index = traverseChoice(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
-                index = traverseSequence(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_ANY)) {
-                index = traverseAny(child);
-                seeParticle = true;
-            } 
-            else {
-                illegalChild = true;
-                reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
-                                  new Object [] { "group", childName });
-            }
-            
-            if ( ! illegalChild ) {
-                index = expandContentModel( index, child);
-            }
-
-            if (seeParticle && seeAll) {
-                reportSchemaError( SchemaMessageProvider.GroupContentRestricted,
-                                   new Object [] { "'all' needs to be 'the' only Child", childName});
-            }
-
-            if (left == -2) {
-                left = index;
-            } else if (right == -2) {
-                right = index;
-            } else {
-                left = fSchemaGrammar.addContentSpecNode(csnType, left, right, false);
-                right = index;
-            }
-        }
-        if (hadContent && right != -2)
-            left = fSchemaGrammar.addContentSpecNode(csnType, left, right, false);
-
-
-        return left;
-    }
-
-    private int traverseGroupDeclFromAnotherSchema( String groupName , String uriStr ) throws Exception {
-        
-        SchemaGrammar aGrammar = (SchemaGrammar) fGrammarResolver.getGrammar(uriStr);
-        if (uriStr == null || aGrammar==null ||! (aGrammar instanceof SchemaGrammar) ) {
-            // REVISIT: Localize
-            reportGenericSchemaError("!!Schema not found in #traverseGroupDeclFromAnotherSchema, "+
-                                     "schema uri: " + uriStr
-                                     +", groupName: " + groupName);
-            return -1;
-        }
-
-
-        Element groupDecl = (Element) aGrammar.topLevelGroupDecls.get((Object)groupName);
-        if (groupDecl == null) {
-            // REVISIT: Localize
-            reportGenericSchemaError( "no group named \"" + groupName 
-                                      + "\" was defined in schema : " + uriStr);
-            return -1;
-        }
-
-        NamespacesScope saveNSMapping = fNamespacesScope;
-        int saveTargetNSUri = fTargetNSURI;
-        fTargetNSURI = fStringPool.addSymbol(aGrammar.getTargetNamespaceURI());
-        fNamespacesScope = aGrammar.getNamespacesScope();
-
-        boolean traverseElt = true; 
-        if (fCurrentScope == TOP_LEVEL_SCOPE) {
-            traverseElt = false;
-        }
-
-        Element child = XUtil.getFirstChildElement(groupDecl);
-        while (child != null && child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION))
-            child = XUtil.getNextSiblingElement(child);
-
-        int contentSpecType = 0;
-        int csnType = 0;
-        int allChildren[] = null;
-        int allChildCount = 0;
-
-        csnType = XMLContentSpec.CONTENTSPECNODE_SEQ;
-        contentSpecType = XMLElementDecl.TYPE_CHILDREN;
-        
-        int left = -2;
-        int right = -2;
-        boolean hadContent = false;
-
-        for (;
-             child != null;
-             child = XUtil.getNextSiblingElement(child)) {
-            int index = -2;
-            hadContent = true;
-
-            boolean seeParticle = false;
-            String childName = child.getNodeName();
-            int childNameIndex = fStringPool.addSymbol(childName);
-            String formAttrVal = child.getAttribute(SchemaSymbols.ATT_FORM);
-            if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
-                QName eltQName = traverseElementDecl(child); 
-                index = fSchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_LEAF,
-                                                       eltQName.localpart,
-                                                       eltQName.uri, 
-                                                       false);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
-                index = traverseGroupDecl(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_ALL)) {
-                index = traverseAll(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
-                index = traverseChoice(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
-                index = traverseSequence(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_ANY)) {
-                index = traverseAny(child);
-                seeParticle = true;
-            } 
-            else {
-                reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
-                                  new Object [] { "group", childName });
-            }
-
-            if (seeParticle) {
-                index = expandContentModel( index, child);
-            }
-            if (left == -2) {
-                left = index;
-            } else if (right == -2) {
-                right = index;
-            } else {
-                left = fSchemaGrammar.addContentSpecNode(csnType, left, right, false);
-                right = index;
-            }
-        }
-        if (hadContent && right != -2)
-            left = fSchemaGrammar.addContentSpecNode(csnType, left, right, false);
-
-        fNamespacesScope = saveNSMapping;
-        fTargetNSURI = saveTargetNSUri;
-        return left;
-
-
-    } // end of method traverseGroupDeclFromAnotherSchema
-    
-    /**
-    *
-    * Traverse the Sequence declaration
-    * 
-    * <sequence 
-    *   id = ID 
-    *   maxOccurs = string 
-    *   minOccurs = nonNegativeInteger>
-    *   Content: (annotation? , (element | group | choice | sequence | any)*)
-    * </sequence>
-    * 
-    **/
-    int traverseSequence (Element sequenceDecl) throws Exception {
-            
-        Element child = XUtil.getFirstChildElement(sequenceDecl);
-        while (child != null && child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION))
-            child = XUtil.getNextSiblingElement(child);
-
-        int contentSpecType = 0;
-        int csnType = 0;
-
-        csnType = XMLContentSpec.CONTENTSPECNODE_SEQ;
-        contentSpecType = XMLElementDecl.TYPE_CHILDREN;
-
-        int left = -2;
-        int right = -2;
-        boolean hadContent = false;
-
-        for (;
-             child != null;
-             child = XUtil.getNextSiblingElement(child)) {
-            int index = -2;
-            hadContent = true;
-
-            boolean seeParticle = false;
-            String childName = child.getNodeName();
-            if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
-                QName eltQName = traverseElementDecl(child);
-                index = fSchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_LEAF,
-                                                       eltQName.localpart,
-                                                       eltQName.uri, 
-                                                       false);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
-                index = traverseGroupDecl(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
-                index = traverseChoice(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
-                index = traverseSequence(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_ANY)) {
-                index = traverseAny(child);
-                seeParticle = true;
-            } 
-            else {
-                reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
-                                  new Object [] { "group", childName });
-            }
-
-            if (seeParticle) {
-                index = expandContentModel( index, child);
-            }
-            if (left == -2) {
-                left = index;
-            } else if (right == -2) {
-                right = index;
-            } else {
-                left = fSchemaGrammar.addContentSpecNode(csnType, left, right, false);
-                right = index;
-            }
-        }
-
-        if (hadContent && right != -2)
-            left = fSchemaGrammar.addContentSpecNode(csnType, left, right, false);
-
-        return left;
-    }
-    
-    /**
-    *
-    * Traverse the Sequence declaration
-    * 
-    * <choice
-    *   id = ID 
-    *   maxOccurs = string 
-    *   minOccurs = nonNegativeInteger>
-    *   Content: (annotation? , (element | group | choice | sequence | any)*)
-    * </choice>
-    * 
-    **/
-    int traverseChoice (Element choiceDecl) throws Exception {
-            
-        // REVISIT: traverseChoice, traverseSequence can be combined
-        Element child = XUtil.getFirstChildElement(choiceDecl);
-        while (child != null && child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION))
-            child = XUtil.getNextSiblingElement(child);
-
-        int contentSpecType = 0;
-        int csnType = 0;
-
-        csnType = XMLContentSpec.CONTENTSPECNODE_CHOICE;
-        contentSpecType = XMLElementDecl.TYPE_CHILDREN;
-
-        int left = -2;
-        int right = -2;
-        boolean hadContent = false;
-
-        for (;
-             child != null;
-             child = XUtil.getNextSiblingElement(child)) {
-            int index = -2;
-            hadContent = true;
-
-            boolean seeParticle = false;
-            String childName = child.getNodeName();
-            if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
-                QName eltQName = traverseElementDecl(child);
-                index = fSchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_LEAF,
-                                                       eltQName.localpart,
-                                                       eltQName.uri, 
-                                                       false);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
-                index = traverseGroupDecl(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
-                index = traverseChoice(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
-                index = traverseSequence(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_ANY)) {
-                index = traverseAny(child);
-                seeParticle = true;
-            } 
-            else {
-                reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
-                                  new Object [] { "group", childName });
-            }
-
-            if (seeParticle) {
-                index = expandContentModel( index, child);
-            }
-            if (left == -2) {
-                left = index;
-            } else if (right == -2) {
-                right = index;
-            } else {
-                left = fSchemaGrammar.addContentSpecNode(csnType, left, right, false);
-                right = index;
-            }
-        }
-
-        if (hadContent && right != -2)
-            left = fSchemaGrammar.addContentSpecNode(csnType, left, right, false);
-
-        return left;
-    }
-    
-
-   /**
-    * 
-    * Traverse the "All" declaration
-    *
-    * <all 
-    *   id = ID 
-    *   maxOccurs = string 
-    *   minOccurs = nonNegativeInteger>
-    *   Content: (annotation? , (element | group | choice | sequence | any)*)
-    * </all>
-    *   
-    **/
-
-    int traverseAll( Element allDecl) throws Exception {
-
-        Element child = XUtil.getFirstChildElement(allDecl);
-
-        while (child != null && child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION))
-            child = XUtil.getNextSiblingElement(child);
-
-        int allChildren[] = null;
-        int allChildCount = 0;
-
-        int left = -2;
-
-        for (;
-             child != null;
-             child = XUtil.getNextSiblingElement(child)) {
-
-            int index = -2;
-            boolean seeParticle = false;
-
-            String childName = child.getNodeName();
-
-            if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
-                QName eltQName = traverseElementDecl(child);
-                index = fSchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_LEAF,
-                                                       eltQName.localpart,
-                                                       eltQName.uri, 
-                                                       false);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
-                index = traverseGroupDecl(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
-                    index = traverseChoice(child);
-                    seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
-                index = traverseSequence(child);
-                seeParticle = true;
-
-            } 
-            else if (childName.equals(SchemaSymbols.ELT_ANY)) {
-                index = traverseAny(child);
-                seeParticle = true;
-            } 
-            else {
-                reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
-                                  new Object [] { "group", childName });
-            }
-
-            if (seeParticle) {
-                index = expandContentModel( index, child);
-            }
-            try {
-                allChildren[allChildCount] = index;
-            }
-            catch (NullPointerException ne) {
-                allChildren = new int[32];
-                allChildren[allChildCount] = index;
-            }
-            catch (ArrayIndexOutOfBoundsException ae) {
-                int[] newArray = new int[allChildren.length*2];
-                System.arraycopy(allChildren, 0, newArray, 0, allChildren.length);
-                allChildren[allChildCount] = index;
-            }
-            allChildCount++;
-        }
-        left = buildAllModel(allChildren,allChildCount);
-
-        return left;
-    }
-    
-    /** builds the all content model */
-    private int buildAllModel(int children[], int count) throws Exception {
-
-        // build all model
-        if (count > 1) {
-
-            // create and initialize singletons
-            XMLContentSpec choice = new XMLContentSpec();
-
-            choice.type = XMLContentSpec.CONTENTSPECNODE_CHOICE;
-            choice.value = -1;
-            choice.otherValue = -1;
-
-            int[] exactChildren = new int[count];
-            System.arraycopy(children,0,exactChildren,0,count);
-            // build all model
-            sort(exactChildren, 0, count);
-            int index = buildAllModel(exactChildren, 0, choice);
-
-            return index;
-        }
-
-        if (count > 0) {
-            return children[0];
-        }
-
-        return -1;
-    }
-
-    /** Builds the all model. */
-    private int buildAllModel(int src[], int offset,
-                              XMLContentSpec choice) throws Exception {
-
-        // swap last two places
-        if (src.length - offset == 2) {
-            int seqIndex = createSeq(src);
-            if (choice.value == -1) {
-                choice.value = seqIndex;
-            }
-            else {
-                if (choice.otherValue != -1) {
-                    choice.value = fSchemaGrammar.addContentSpecNode(choice.type, choice.value, choice.otherValue, false);
-                }
-                choice.otherValue = seqIndex;
-            }
-            swap(src, offset, offset + 1);
-            seqIndex = createSeq(src);
-            if (choice.value == -1) {
-                choice.value = seqIndex;
-            }
-            else {
-                if (choice.otherValue != -1) {
-                    choice.value = fSchemaGrammar.addContentSpecNode(choice.type, choice.value, choice.otherValue, false);
-                }
-                choice.otherValue = seqIndex;
-            }
-            return fSchemaGrammar.addContentSpecNode(choice.type, choice.value, choice.otherValue, false);
-        }
-
-        // recurse
-        for (int i = offset; i < src.length - 1; i++) {
-            choice.value = buildAllModel(src, offset + 1, choice);
-            choice.otherValue = -1;
-            sort(src, offset, src.length - offset);
-            shift(src, offset, i + 1);
-        }
-
-        int choiceIndex = buildAllModel(src, offset + 1, choice);
-        sort(src, offset, src.length - offset);
-
-        return choiceIndex;
-
-    } // buildAllModel(int[],int,ContentSpecNode,ContentSpecNode):int
-
-    /** Creates a sequence. */
-    private int createSeq(int src[]) throws Exception {
-
-        int left = src[0];
-        int right = src[1];
-
-        for (int i = 2; i < src.length; i++) {
-            left = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
-                                                       left, right, false);
-            right = src[i];
-        }
-
-        return fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
-                                                   left, right, false);
-
-    } // createSeq(int[]):int
-
-    /** Shifts a value into position. */
-    private void shift(int src[], int pos, int offset) {
-
-        int temp = src[offset];
-        for (int i = offset; i > pos; i--) {
-            src[i] = src[i - 1];
-        }
-        src[pos] = temp;
-
-    } // shift(int[],int,int)
-
-    /** Simple sort. */
-    private void sort(int src[], final int offset, final int length) {
-
-        for (int i = offset; i < offset + length - 1; i++) {
-            int lowest = i;
-            for (int j = i + 1; j < offset + length; j++) {
-                if (src[j] < src[lowest]) {
-                    lowest = j;
-                }
-            }
-            if (lowest != i) {
-                int temp = src[i];
-                src[i] = src[lowest];
-                src[lowest] = temp;
-            }
-        }
-
-    } // sort(int[],int,int)
-
-    /** Swaps two values. */
-    private void swap(int src[], int i, int j) {
-
-        int temp = src[i];
-        src[i] = src[j];
-        src[j] = temp;
-
-    } // swap(int[],int,int)
-
-    /**
-     * Traverse Wildcard declaration
-     * 
-     * <any 
-     *   id = ID 
-     *   maxOccurs = string 
-     *   minOccurs = nonNegativeInteger 
-     *   namespace = ##any | ##other | ##local | list of {uri, ##targetNamespace} 
-     *   processContents = lax | skip | strict>
-     *   Content: (annotation?)
-     * </any>
-     * @param elementDecl
-     * @return 
-     * @exception Exception
-     */
-    private int traverseWildcardDecl( Element wildcardDecl ) throws Exception {
-        int wildcardID         =  fStringPool.addSymbol(
-                                                       wildcardDecl.getAttribute( SchemaSymbols.ATTVAL_ID ));
-
-        int wildcardMaxOccurs  =  fStringPool.addSymbol(
-                                                       wildcardDecl.getAttribute( SchemaSymbols.ATT_MAXOCCURS ));
-
-        int wildcardMinOccurs  =  fStringPool.addSymbol(
-                                                       wildcardDecl.getAttribute( SchemaSymbols.ATT_MINOCCURS ));
-
-        int wildcardNamespace  =  fStringPool.addSymbol(
-                                                       wildcardDecl.getAttribute( SchemaSymbols.ATT_NAMESPACE ));
-
-        int wildcardProcessContents =  fStringPool.addSymbol(
-                                                            wildcardDecl.getAttribute( SchemaSymbols.ATT_PROCESSCONTENTS ));
-
-
-        int wildcardContent =  fStringPool.addSymbol(
-                                                    wildcardDecl.getAttribute( SchemaSymbols.ATT_CONTENT ));
-
-
-        return -1;
-    }
-    
-    
-
-    // utilities from Tom Watson's SchemaParser class
-    // TO DO: Need to make this more conformant with Schema int type parsing
-
-    private int parseInt (String intString) throws Exception
-    {
-            if ( intString.equals("*") ) {
-                    return SchemaSymbols.INFINITY;
-            } else {
-                    return Integer.parseInt (intString);
-            }
-    }
-
-    private int parseSimpleDerivedBy (String derivedByString) throws Exception
-    {
-            if ( derivedByString.equals (SchemaSymbols.ATTVAL_LIST) ) {
-                    return SchemaSymbols.LIST;
-            } 
-            else if ( derivedByString.equals (SchemaSymbols.ATTVAL_RESTRICTION) ) {
-                    return SchemaSymbols.RESTRICTION;
-            }  
-            else {
-                // REVISIT: Localize
-                    reportGenericSchemaError ("SimpleType: Invalid value for 'derivedBy'");
-                    return -1;
-            }
-    }
-
-    private int parseComplexDerivedBy (String derivedByString)  throws Exception
-    {
-            if ( derivedByString.equals (SchemaSymbols.ATTVAL_EXTENSION) ) {
-                    return SchemaSymbols.EXTENSION;
-            } 
-            else if ( derivedByString.equals (SchemaSymbols.ATTVAL_RESTRICTION) ) {
-                    return SchemaSymbols.RESTRICTION;
-            } 
-            else {
-                // REVISIT: Localize
-                    reportGenericSchemaError ( "ComplexType: Invalid value for 'derivedBy'" );
-                    return -1;
-            }
-    }
-
-    private int parseSimpleFinal (String finalString) throws Exception
-    {
-            if ( finalString.equals (SchemaSymbols.ATTVAL_POUNDALL) ) {
-                    return SchemaSymbols.ENUMERATION+SchemaSymbols.RESTRICTION+SchemaSymbols.LIST+SchemaSymbols.REPRODUCTION;
-            } else {
-                    int enumerate = 0;
-                    int restrict = 0;
-                    int list = 0;
-                    int reproduce = 0;
-
-                    StringTokenizer t = new StringTokenizer (finalString, " ");
-                    while (t.hasMoreTokens()) {
-                            String token = t.nextToken ();
-
-                            if ( token.equals (SchemaSymbols.ATTVAL_RESTRICTION) ) {
-                                    if ( restrict == 0 ) {
-                                            restrict = SchemaSymbols.RESTRICTION;
-                                    } else {
-                                        // REVISIT: Localize
-                                            reportGenericSchemaError ("restriction in set twice");
-                                    }
-                            } else if ( token.equals (SchemaSymbols.ATTVAL_LIST) ) {
-                                    if ( list == 0 ) {
-                                            list = SchemaSymbols.LIST;
-                                    } else {
-                                        // REVISIT: Localize
-                                            reportGenericSchemaError ("list in set twice");
-                                    }
-                            }
-                            else {
-                                // REVISIT: Localize
-                                reportGenericSchemaError (  "Invalid value (" + 
-                                                            finalString +
-                                                            ")" );
-                            }
-                    }
-
-                    return enumerate+restrict+list+reproduce;
-            }
-    }
-
-    private int parseComplexContent (String contentString)  throws Exception
-    {
-            if ( contentString.equals (SchemaSymbols.ATTVAL_EMPTY) ) {
-                    return XMLElementDecl.TYPE_EMPTY;
-            } else if ( contentString.equals (SchemaSymbols.ATTVAL_ELEMENTONLY) ) {
-                    return XMLElementDecl.TYPE_CHILDREN;
-            } else if ( contentString.equals (SchemaSymbols.ATTVAL_TEXTONLY) ) {
-                    return XMLElementDecl.TYPE_SIMPLE;
-            } else if ( contentString.equals (SchemaSymbols.ATTVAL_MIXED) ) {
-                    return XMLElementDecl.TYPE_MIXED;
-            } else {
-                // REVISIT: Localize
-                    reportGenericSchemaError ( "Invalid value for content" );
-                    return -1;
-            }
-    }
-
-    private int parseDerivationSet (String finalString)  throws Exception
-    {
-            if ( finalString.equals ("#all") ) {
-                    return SchemaSymbols.EXTENSION+SchemaSymbols.RESTRICTION+SchemaSymbols.REPRODUCTION;
-            } else {
-                    int extend = 0;
-                    int restrict = 0;
-                    int reproduce = 0;
-
-                    StringTokenizer t = new StringTokenizer (finalString, " ");
-                    while (t.hasMoreTokens()) {
-                            String token = t.nextToken ();
-
-                            if ( token.equals (SchemaSymbols.ATTVAL_EXTENSION) ) {
-                                    if ( extend == 0 ) {
-                                            extend = SchemaSymbols.EXTENSION;
-                                    } else {
-                                        // REVISIT: Localize
-                                            reportGenericSchemaError ( "extension already in set" );
-                                    }
-                            } else if ( token.equals (SchemaSymbols.ATTVAL_RESTRICTION) ) {
-                                    if ( restrict == 0 ) {
-                                            restrict = SchemaSymbols.RESTRICTION;
-                                    } else {
-                                        // REVISIT: Localize
-                                            reportGenericSchemaError ( "restriction already in set" );
-                                    }
-                            } else {
-                                // REVISIT: Localize
-                                    reportGenericSchemaError ( "Invalid final value (" + finalString + ")" );
-                            }
-                    }
-
-                    return extend+restrict+reproduce;
-            }
-    }
-
-    private int parseBlockSet (String finalString)  throws Exception
-    {
-            if ( finalString.equals ("#all") ) {
-                    return SchemaSymbols.EQUIVCLASS+SchemaSymbols.EXTENSION+SchemaSymbols.LIST+SchemaSymbols.RESTRICTION+SchemaSymbols.REPRODUCTION;
-            } else {
-                    int extend = 0;
-                    int restrict = 0;
-                    int reproduce = 0;
-
-                    StringTokenizer t = new StringTokenizer (finalString, " ");
-                    while (t.hasMoreTokens()) {
-                            String token = t.nextToken ();
-
-                            if ( token.equals (SchemaSymbols.ATTVAL_EQUIVCLASS) ) {
-                                    if ( extend == 0 ) {
-                                            extend = SchemaSymbols.EQUIVCLASS;
-                                    } else {
-                                        // REVISIT: Localize
-                                            reportGenericSchemaError ( "'equivClass' already in set" );
-                                    }
-                            } else if ( token.equals (SchemaSymbols.ATTVAL_EXTENSION) ) {
-                                    if ( extend == 0 ) {
-                                            extend = SchemaSymbols.EXTENSION;
-                                    } else {
-                                        // REVISIT: Localize
-                                            reportGenericSchemaError ( "extension already in set" );
-                                    }
-                            } else if ( token.equals (SchemaSymbols.ATTVAL_LIST) ) {
-                                    if ( extend == 0 ) {
-                                            extend = SchemaSymbols.LIST;
-                                    } else {
-                                        // REVISIT: Localize
-                                            reportGenericSchemaError ( "'list' already in set" );
-                                    }
-                            } else if ( token.equals (SchemaSymbols.ATTVAL_RESTRICTION) ) {
-                                    if ( restrict == 0 ) {
-                                            restrict = SchemaSymbols.RESTRICTION;
-                                    } else {
-                                        // REVISIT: Localize
-                                            reportGenericSchemaError ( "restriction already in set" );
-                                    }
-                            } else {
-                                // REVISIT: Localize
-                                    reportGenericSchemaError ( "Invalid final value (" + finalString + ")" );
-                            }
-                    }
-
-                    return extend+restrict+reproduce;
-            }
-    }
-
-    private int parseFinalSet (String finalString)  throws Exception
-    {
-            if ( finalString.equals ("#all") ) {
-                    return SchemaSymbols.EQUIVCLASS+SchemaSymbols.EXTENSION+SchemaSymbols.LIST+SchemaSymbols.RESTRICTION+SchemaSymbols.REPRODUCTION;
-            } else {
-                    int extend = 0;
-                    int restrict = 0;
-                    int reproduce = 0;
-
-                    StringTokenizer t = new StringTokenizer (finalString, " ");
-                    while (t.hasMoreTokens()) {
-                            String token = t.nextToken ();
-
-                            if ( token.equals (SchemaSymbols.ATTVAL_EQUIVCLASS) ) {
-                                    if ( extend == 0 ) {
-                                            extend = SchemaSymbols.EQUIVCLASS;
-                                    } else {
-                                        // REVISIT: Localize
-                                            reportGenericSchemaError ( "'equivClass' already in set" );
-                                    }
-                            } else if ( token.equals (SchemaSymbols.ATTVAL_EXTENSION) ) {
-                                    if ( extend == 0 ) {
-                                            extend = SchemaSymbols.EXTENSION;
-                                    } else {
-                                        // REVISIT: Localize
-                                            reportGenericSchemaError ( "extension already in set" );
-                                    }
-                            } else if ( token.equals (SchemaSymbols.ATTVAL_LIST) ) {
-                                    if ( extend == 0 ) {
-                                            extend = SchemaSymbols.LIST;
-                                    } else {
-                                        // REVISIT: Localize
-                                            reportGenericSchemaError ( "'list' already in set" );
-                                    }
-                            } else if ( token.equals (SchemaSymbols.ATTVAL_RESTRICTION) ) {
-                                    if ( restrict == 0 ) {
-                                            restrict = SchemaSymbols.RESTRICTION;
-                                    } else {
-                                        // REVISIT: Localize
-                                            reportGenericSchemaError ( "restriction already in set" );
-                                    }
-                            } else {
-                                // REVISIT: Localize
-                                    reportGenericSchemaError ( "Invalid final value (" + finalString + ")" );
-                            }
-                    }
-
-                    return extend+restrict+reproduce;
-            }
-    }
-
-    private void reportGenericSchemaError (String error) throws Exception {
-        if (fErrorReporter == null) {
-            System.err.println("__TraverseSchemaError__ : " + error);       
-        }
-        else {
-            reportSchemaError (SchemaMessageProvider.GenericError, new Object[] { error });
-        }        
-    }
-
-
-    private void reportSchemaError(int major, Object args[]) throws Exception {
-        if (fErrorReporter == null) {
-            System.out.println("__TraverseSchemaError__ : " + SchemaMessageProvider.fgMessageKeys[major]);
-            for (int i=0; i< args.length ; i++) {
-                System.out.println((String)args[i]);    
-            }
-        }
-        else {
-            fErrorReporter.reportError(fErrorReporter.getLocator(),
-                                       SchemaMessageProvider.SCHEMA_DOMAIN,
-                                       major,
-                                       SchemaMessageProvider.MSG_NONE,
-                                       args,
-                                       XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
-        }
-    }
-
-    //Unit Test here
-    public static void main(String args[] ) {
-
-        if( args.length != 1 ) {
-            System.out.println( "Error: Usage java TraverseSchema yourFile.xsd" );
-            System.exit(0);
-        }
-
-        DOMParser parser = new DOMParser() {
-            public void ignorableWhitespace(char ch[], int start, int length) {}
-            public void ignorableWhitespace(int dataIdx) {}
-        };
-        parser.setEntityResolver( new Resolver() );
-        parser.setErrorHandler(  new ErrorHandler() );
-
-        try {
-        parser.setFeature("http://xml.org/sax/features/validation", false);
-        parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
-        }catch(  org.xml.sax.SAXNotRecognizedException e ) {
-            e.printStackTrace();
-        }catch( org.xml.sax.SAXNotSupportedException e ) {
-            e.printStackTrace();
-        }
-
-        try {
-        parser.parse( args[0]);
-        }catch( IOException e ) {
-            e.printStackTrace();
-        }catch( SAXException e ) {
-            e.printStackTrace();
-        }
-
-        Document     document   = parser.getDocument(); //Our Grammar
-
-        OutputFormat    format  = new OutputFormat( document );
-        java.io.StringWriter outWriter = new java.io.StringWriter();
-        XMLSerializer    serial = new XMLSerializer( outWriter,format);
-
-        TraverseSchema tst = null;
-        try {
-            Element root   = document.getDocumentElement();// This is what we pass to TraverserSchema
-            //serial.serialize( root );
-            //System.out.println(outWriter.toString());
-
-            tst = new TraverseSchema( root, new StringPool(), new SchemaGrammar(), (GrammarResolver) new GrammarResolverImpl() );
-            }
-            catch (Exception e) {
-                e.printStackTrace(System.err);
-            }
-            
-            parser.getDocument();
-    }
-
-    static class Resolver implements EntityResolver {
-        private static final String SYSTEM[] = {
-            "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/structures.dtd",
-            "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/datatypes.dtd",
-            "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/versionInfo.ent",
-        };
-        private static final String PATH[] = {
-            "structures.dtd",
-            "datatypes.dtd",
-            "versionInfo.ent",
-        };
-
-        public InputSource resolveEntity(String publicId, String systemId)
-        throws IOException {
-
-            // looking for the schema DTDs?
-            for (int i = 0; i < SYSTEM.length; i++) {
-                if (systemId.equals(SYSTEM[i])) {
-                    InputSource source = new InputSource(getClass().getResourceAsStream(PATH[i]));
-                    source.setPublicId(publicId);
-                    source.setSystemId(systemId);
-                    return source;
-                }
-            }
-
-            // use default resolution
-            return null;
-
-        } // resolveEntity(String,String):InputSource
-
-    } // class Resolver
-
-    static class ErrorHandler implements org.xml.sax.ErrorHandler {
-
-        /** Warning. */
-        public void warning(SAXParseException ex) {
-            System.err.println("[Warning] "+
-                               getLocationString(ex)+": "+
-                               ex.getMessage());
-        }
-
-        /** Error. */
-        public void error(SAXParseException ex) {
-            System.err.println("[Error] "+
-                               getLocationString(ex)+": "+
-                               ex.getMessage());
-        }
-
-        /** Fatal error. */
-        public void fatalError(SAXParseException ex) throws SAXException {
-            System.err.println("[Fatal Error] "+
-                               getLocationString(ex)+": "+
-                               ex.getMessage());
-            throw ex;
-        }
-
-        //
-        // Private methods
-        //
-
-        /** Returns a string of the location. */
-        private String getLocationString(SAXParseException ex) {
-            StringBuffer str = new StringBuffer();
-
-            String systemId_ = ex.getSystemId();
-            if (systemId_ != null) {
-                int index = systemId_.lastIndexOf('/');
-                if (index != -1)
-                    systemId_ = systemId_.substring(index + 1);
-                str.append(systemId_);
-            }
-            str.append(':');
-            str.append(ex.getLineNumber());
-            str.append(':');
-            str.append(ex.getColumnNumber());
-
-            return str.toString();
-
-        } // getLocationString(SAXParseException):String
-    }
-
-
-}
-
-
-
-
-
diff --git a/src/org/apache/xerces/validators/schema/XUtil.java b/src/org/apache/xerces/validators/schema/XUtil.java
deleted file mode 100644
index 678459e..0000000
--- a/src/org/apache/xerces/validators/schema/XUtil.java
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xerces.validators.schema;
-
-import org.apache.xerces.dom.AttrImpl;
-import org.apache.xerces.dom.DocumentImpl;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-
-/**
- * Some useful utility methods.
- */
-public class XUtil {
-
-    //
-    // Constructors
-    //
-
-    /** This class cannot be instantiated. */
-    protected XUtil() {}
-
-    //
-    // Public static methods
-    //
-
-    /**
-     * Copies the source tree into the specified place in a destination
-     * tree. The source node and its children are appended as children
-     * of the destination node.
-     * <p>
-     * <em>Note:</em> This is an iterative implementation.
-     */
-    public static void copyInto(Node src, Node dest) throws DOMException {
-
-        // get node factory
-        Document factory = dest.getOwnerDocument();
-        boolean domimpl = factory instanceof DocumentImpl;
-
-        // placement variables
-        Node start  = src;
-        Node parent = src;
-        Node place  = src;
-
-        // traverse source tree
-        while (place != null) {
-
-            // copy this node
-            Node node = null;
-            int  type = place.getNodeType();
-            switch (type) {
-                case Node.CDATA_SECTION_NODE: {
-                    node = factory.createCDATASection(place.getNodeValue());
-                    break;
-                }
-                case Node.COMMENT_NODE: {
-                    node = factory.createComment(place.getNodeValue());
-                    break;
-                }
-                case Node.ELEMENT_NODE: {
-                    Element element = factory.createElement(place.getNodeName());
-                    node = element;
-                    NamedNodeMap attrs  = place.getAttributes();
-                    int attrCount = attrs.getLength();
-                    for (int i = 0; i < attrCount; i++) {
-                        Attr attr = (Attr)attrs.item(i);
-                        String attrName = attr.getNodeName();
-                        String attrValue = attr.getNodeValue();
-                        element.setAttribute(attrName, attrValue);
-                        if (domimpl && !attr.getSpecified()) {
-                            ((AttrImpl)element.getAttributeNode(attrName)).setSpecified(false);
-                        }
-                    }
-                    break;
-                }
-                case Node.ENTITY_REFERENCE_NODE: {
-                    node = factory.createEntityReference(place.getNodeName());
-                    break;
-                }
-                case Node.PROCESSING_INSTRUCTION_NODE: {
-                    node = factory.createProcessingInstruction(place.getNodeName(),
-                                                               place.getNodeValue());
-                    break;
-                }
-                case Node.TEXT_NODE: {
-                    node = factory.createTextNode(place.getNodeValue());
-                    break;
-                }
-                default: {
-                    throw new IllegalArgumentException("can't copy node type, "+
-                                                       type+" ("+
-                                                       node.getNodeName()+')');
-                }
-            }
-            dest.appendChild(node);
-
-            // iterate over children
-            if (place.hasChildNodes()) {
-                parent = place;
-                place  = place.getFirstChild();
-                dest   = node;
-            }
-
-            // advance
-            else {
-                place = place.getNextSibling();
-                while (place == null && parent != start) {
-                    place  = parent.getNextSibling();
-                    parent = parent.getParentNode();
-                    dest   = dest.getParentNode();
-                }
-            }
-
-        }
-
-    } // copyInto(Node,Node)
-
-    /** Finds and returns the first child element node. */
-    public static Element getFirstChildElement(Node parent) {
-
-        // search for node
-        Node child = parent.getFirstChild();
-        while (child != null) {
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                return (Element)child;
-            }
-            child = child.getNextSibling();
-        }
-
-        // not found
-        return null;
-
-    } // getFirstChildElement(Node):Element
-
-    /** Finds and returns the last child element node. */
-    public static Element getLastChildElement(Node parent) {
-
-        // search for node
-        Node child = parent.getLastChild();
-        while (child != null) {
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                return (Element)child;
-            }
-            child = child.getPreviousSibling();
-        }
-
-        // not found
-        return null;
-
-    } // getLastChildElement(Node):Element
-
-    /** Finds and returns the next sibling element node. */
-    public static Element getNextSiblingElement(Node node) {
-
-        // search for node
-        Node sibling = node.getNextSibling();
-        while (sibling != null) {
-            if (sibling.getNodeType() == Node.ELEMENT_NODE) {
-                return (Element)sibling;
-            }
-            sibling = sibling.getNextSibling();
-        }
-
-        // not found
-        return null;
-
-    } // getNextSiblingdElement(Node):Element
-
-    /** Finds and returns the first child node with the given name. */
-    public static Element getFirstChildElement(Node parent, String elemName) {
-
-        // search for node
-        Node child = parent.getFirstChild();
-        while (child != null) {
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                if (child.getNodeName().equals(elemName)) {
-                    return (Element)child;
-                }
-            }
-            child = child.getNextSibling();
-        }
-
-        // not found
-        return null;
-
-    } // getFirstChildElement(Node,String):Element
-
-    /** Finds and returns the last child node with the given name. */
-    public static Element getLastChildElement(Node parent, String elemName) {
-
-        // search for node
-        Node child = parent.getLastChild();
-        while (child != null) {
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                if (child.getNodeName().equals(elemName)) {
-                    return (Element)child;
-                }
-            }
-            child = child.getPreviousSibling();
-        }
-
-        // not found
-        return null;
-
-    } // getLastChildElement(Node,String):Element
-
-    /** Finds and returns the next sibling node with the given name. */
-    public static Element getNextSiblingElement(Node node, String elemName) {
-
-        // search for node
-        Node sibling = node.getNextSibling();
-        while (sibling != null) {
-            if (sibling.getNodeType() == Node.ELEMENT_NODE) {
-                if (sibling.getNodeName().equals(elemName)) {
-                    return (Element)sibling;
-                }
-            }
-            sibling = sibling.getNextSibling();
-        }
-
-        // not found
-        return null;
-
-    } // getNextSiblingdElement(Node,String):Element
-
-    /** Finds and returns the first child node with the given name. */
-    public static Element getFirstChildElement(Node parent, String elemNames[]) {
-
-        // search for node
-        Node child = parent.getFirstChild();
-        while (child != null) {
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                for (int i = 0; i < elemNames.length; i++) {
-                    if (child.getNodeName().equals(elemNames[i])) {
-                        return (Element)child;
-                    }
-                }
-            }
-            child = child.getNextSibling();
-        }
-
-        // not found
-        return null;
-
-    } // getFirstChildElement(Node,String[]):Element
-
-    /** Finds and returns the last child node with the given name. */
-    public static Element getLastChildElement(Node parent, String elemNames[]) {
-
-        // search for node
-        Node child = parent.getLastChild();
-        while (child != null) {
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                for (int i = 0; i < elemNames.length; i++) {
-                    if (child.getNodeName().equals(elemNames[i])) {
-                        return (Element)child;
-                    }
-                }
-            }
-            child = child.getPreviousSibling();
-        }
-
-        // not found
-        return null;
-
-    } // getLastChildElement(Node,String[]):Element
-
-    /** Finds and returns the next sibling node with the given name. */
-    public static Element getNextSiblingElement(Node node, String elemNames[]) {
-
-        // search for node
-        Node sibling = node.getNextSibling();
-        while (sibling != null) {
-            if (sibling.getNodeType() == Node.ELEMENT_NODE) {
-                for (int i = 0; i < elemNames.length; i++) {
-                    if (sibling.getNodeName().equals(elemNames[i])) {
-                        return (Element)sibling;
-                    }
-                }
-            }
-            sibling = sibling.getNextSibling();
-        }
-
-        // not found
-        return null;
-
-    } // getNextSiblingdElement(Node,String[]):Element
-
-    /**
-     * Finds and returns the first child node with the given name and
-     * attribute name, value pair.
-     */
-    public static Element getFirstChildElement(Node   parent,
-                                               String elemName,
-                                               String attrName,
-                                               String attrValue) {
-
-        // search for node
-        Node child = parent.getFirstChild();
-        while (child != null) {
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                Element element = (Element)child;
-                if (element.getNodeName().equals(elemName) &&
-                    element.getAttribute(attrName).equals(attrValue)) {
-                    return element;
-                }
-            }
-            child = child.getNextSibling();
-        }
-
-        // not found
-        return null;
-
-    } // getFirstChildElement(Node,String,String,String):Element
-
-    /**
-     * Finds and returns the last child node with the given name and
-     * attribute name, value pair.
-     */
-    public static Element getLastChildElement(Node   parent,
-                                               String elemName,
-                                               String attrName,
-                                               String attrValue) {
-
-        // search for node
-        Node child = parent.getLastChild();
-        while (child != null) {
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                Element element = (Element)child;
-                if (element.getNodeName().equals(elemName) &&
-                    element.getAttribute(attrName).equals(attrValue)) {
-                    return element;
-                }
-            }
-            child = child.getPreviousSibling();
-        }
-
-        // not found
-        return null;
-
-    } // getLastChildElement(Node,String,String,String):Element
-
-    /**
-     * Finds and returns the next sibling node with the given name and
-     * attribute name, value pair. Since only elements have attributes,
-     * the node returned will be of type Node.ELEMENT_NODE.
-     */
-    public static Element getNextSiblingElement(Node   node,
-                                                String elemName,
-                                                String attrName,
-                                                String attrValue) {
-
-        // search for node
-        Node sibling = node.getNextSibling();
-        while (sibling != null) {
-            if (sibling.getNodeType() == Node.ELEMENT_NODE) {
-                Element element = (Element)sibling;
-                if (element.getNodeName().equals(elemName) &&
-                    element.getAttribute(attrName).equals(attrValue)) {
-                    return element;
-                }
-            }
-            sibling = sibling.getNextSibling();
-        }
-
-        // not found
-        return null;
-
-    } // getNextSiblingElement(Node,String,String,String):Element
-
-} // class XUtil
diff --git a/src/org/apache/xerces/validators/schema/datatypes.dtd b/src/org/apache/xerces/validators/schema/datatypes.dtd
deleted file mode 100644
index 4f391b1..0000000
--- a/src/org/apache/xerces/validators/schema/datatypes.dtd
+++ /dev/null
@@ -1,158 +0,0 @@
-<!-- DTD for XML Schemas: Part 2: Datatypes -->
-<!-- $Id$ -->
-<!-- Note this DTD is NOT the normative datatypes DTD - - the
-     prose copy in the datatypes REC is the normative version (which
-     shouldn't differ from this one except for this comment and entity
-     expansions, but just in case -->
-<!ENTITY % p ''> <!-- can be overriden in the internal subset of a
-                      schema document to establish a namespace prefix -->
-<!-- Define all the element names, with optional prefix -->
-<!ENTITY % simpleType "%p;simpleType">
-<!ENTITY % maxExclusive "%p;maxExclusive">
-<!ENTITY % minExclusive "%p;minExclusive">
-<!ENTITY % maxInclusive "%p;maxInclusive">
-<!ENTITY % minInclusive "%p;minInclusive">
-<!ENTITY % precision "%p;precision">
-<!ENTITY % scale "%p;scale">
-<!ENTITY % length "%p;length">
-<!ENTITY % minLength "%p;minLength">
-<!ENTITY % maxLength "%p;maxLength">
-<!ENTITY % enumeration "%p;enumeration">
-<!ENTITY % pattern "%p;pattern">
-<!ENTITY % encoding "%p;encoding">
-<!ENTITY % period "%p;period">
-<!ENTITY % duration "%p;duration">
-
-<!-- Customisation entities for the ATTLIST of each element type.
-     Define one of these if your schema takes advantage of the
-     anyAttribute='##other' in the schema for schemas -->
-
-<!ENTITY % simpleTypeAttrs ''>
-<!ENTITY % maxExclusiveAttrs ''>
-<!ENTITY % minExclusiveAttrs ''>
-<!ENTITY % maxInclusiveAttrs ''>
-<!ENTITY % minInclusiveAttrs ''>
-<!ENTITY % precisionAttrs ''>
-<!ENTITY % scaleAttrs ''>
-<!ENTITY % lengthAttrs ''>
-<!ENTITY % minLengthAttrs ''>
-<!ENTITY % maxLengthAttrs ''>
-<!ENTITY % enumerationAttrs ''>
-<!ENTITY % patternAttrs ''>
-<!ENTITY % encodingAttrs ''>
-<!ENTITY % periodAttrs ''>
-<!ENTITY % durationAttrs ''>
-<!ENTITY % appinfoAttrs ''>
-<!ENTITY % documentationAttrs ''>
-
-
-<!-- annotation elements -->
-<!ENTITY % annotation "%p;annotation">
-<!ENTITY % appinfo "%p;appinfo">
-<!ENTITY % documentation "%p;documentation">
-
-
-<!-- Define some entities for informative use as attribute types -->
-<!ENTITY % URIref "CDATA">
-<!ENTITY % QName "CDATA">
-<!ENTITY % NCName "NMTOKEN">
-<!ENTITY % nonNegativeInteger "NMTOKEN">
-<!ENTITY % boolean "(true|false)">
-<!ENTITY % simpleDerivationChoice "(list|restriction)">
-
-<!-- Note that the use of 'facet' below is less restrictive than is
-     really intended:  There should in fact be no more than one of each of
-     minInclusive, minExclusive, maxInclusive, maxExclusive,
-     precision, scale,
-     length, maxLength, minLength, encoding, period within datatype,
-     and the min- and max- variants of Inclusive and Exclusive are
-     mutually exclusive.
-     On the other hand,  pattern and enumeration may repeat -->
-<!ENTITY % minBound '(%minInclusive; | %minExclusive;)'>
-<!ENTITY % maxBound '(%maxInclusive; | %maxExclusive;)'>
-<!ENTITY % bounds '%minBound; | %maxBound;'>
-<!ENTITY % numeric '%precision; | %scale;'>
-<!ENTITY % ordered '%bounds; | %numeric;'>
-<!ENTITY % unordered
-   '%pattern; | %enumeration; | %length; | %maxLength; | %minLength;
-    | %encoding; | %period; | %duration;'>
-<!ENTITY % facet '%ordered; | %unordered;'>
-<!ENTITY % facetAttr 'value CDATA #REQUIRED'>
-<!ENTITY % facetModel '(%annotation;)?'>
-<!ELEMENT %simpleType; ((%annotation;)?,(%facet;)*)>
-<!ATTLIST %simpleType;
-    name      %NCName;                 #IMPLIED
-    base      %QName;                  #REQUIRED
-    derivedBy %simpleDerivationChoice; 'restriction'
-    %simpleTypeAttrs;>
-<!-- name is required at top level -->
-
-<!ELEMENT %maxExclusive; %facetModel;>
-<!ATTLIST %maxExclusive; %facetAttr;
-          %maxExclusiveAttrs;>
-<!ELEMENT %minExclusive; %facetModel;>
-<!ATTLIST %minExclusive; %facetAttr;
-          %minExclusiveAttrs;>
-
-<!ELEMENT %maxInclusive; %facetModel;>
-<!ATTLIST %maxInclusive; %facetAttr;
-          %maxInclusiveAttrs;>
-<!ELEMENT %minInclusive; %facetModel;>
-<!ATTLIST %minInclusive; %facetAttr;
-          %minInclusiveAttrs;>
-
-<!ELEMENT %precision; %facetModel;>
-<!ATTLIST %precision; %facetAttr;
-          %precisionAttrs;>
-<!ELEMENT %scale; %facetModel;>
-<!ATTLIST %scale; %facetAttr;
-          %scaleAttrs;>
-
-<!ELEMENT %length; %facetModel;>
-<!ATTLIST %length; %facetAttr;
-          %lengthAttrs;>
-<!ELEMENT %minLength; %facetModel;>
-<!ATTLIST %minLength; %facetAttr;
-          %minLengthAttrs;>
-<!ELEMENT %maxLength; %facetModel;>
-<!ATTLIST %maxLength; %facetAttr;
-          %maxLengthAttrs;>
-
-<!-- This one can be repeated -->
-<!ELEMENT %enumeration; %facetModel;>
-<!ATTLIST %enumeration; %facetAttr;
-          %enumerationAttrs;>
-
-<!-- This one can be repeated -->
-<!ELEMENT %pattern; %facetModel;>
-<!ATTLIST %pattern; %facetAttr;
-          %patternAttrs;>
-
-<!ELEMENT %encoding; %facetModel;>
-<!ATTLIST %encoding; %facetAttr;
-          %encodingAttrs;>
-<!ELEMENT %period; %facetModel;>
-<!ATTLIST %period; %facetAttr;
-          %periodAttrs;>
-<!ELEMENT %duration; %facetModel;>
-<!ATTLIST %duration; %facetAttr;
-          %durationAttrs;>
-
-<!-- Annotation is either application information or documentation -->
-<!-- By having these here they are available for datatypes as well
-     as all the structures elements -->
-
-<!ELEMENT %annotation; (%appinfo; | %documentation;)*>
-
-<!-- User must define annotation elements in internal subset for this
-     to work -->
-<!ELEMENT %appinfo; ANY>   <!-- too restrictive -->
-<!ATTLIST %appinfo;
-          source     %URIref;      #IMPLIED
-          %appinfoAttrs;>
-<!ELEMENT %documentation; ANY>   <!-- too restrictive -->
-<!ATTLIST %documentation;
-          source     %URIref;   #IMPLIED
-          xml:lang   CDATA      #IMPLIED
-          %documentationAttrs;>
-
diff --git a/src/org/apache/xerces/validators/schema/structures.dtd b/src/org/apache/xerces/validators/schema/structures.dtd
deleted file mode 100644
index 3cc32e0..0000000
--- a/src/org/apache/xerces/validators/schema/structures.dtd
+++ /dev/null
@@ -1,328 +0,0 @@
-<!-- DTD for XML Schemas: Part 1: Structures -->
-<!-- $Id$ -->
-<!-- Note this DTD is NOT the normative structures DTD - - the
-     prose copy in the structures REC is the normative version (which
-     shouldn't differ from this one except for this comment and entity
-     expansions, but just in case -->
-<!ENTITY % versionEntities SYSTEM "versionInfo.ent">
-%versionEntities; <!-- get path and date entities -->
-
-<!-- The the datatype element and its components
-     are defined in XML Schema: Part 2: Datatypes -->
-<!-- Note %p is defined in datatypes.dtd -->
-<!ENTITY % xs-datatypes PUBLIC 'datatypes'
-                     "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/datatypes.dtd" >
-%xs-datatypes;
-
-<!ENTITY % s ''> <!-- if %p is defined (e.g. as foo:) then you must
-                      also define %s as the suffix for the appropriate
-                      namespace declaration (e.g. :foo) -->
-<!ENTITY % nds 'xmlns%s;'>
-
-<!-- Define all the element names, with optional prefix -->
-<!ENTITY % schema "%p;schema">
-<!ENTITY % complexType "%p;complexType">
-<!ENTITY % element "%p;element">
-<!ENTITY % unique "%p;unique">
-<!ENTITY % key "%p;key">
-<!ENTITY % keyref "%p;keyref">
-<!ENTITY % selector "%p;selector">
-<!ENTITY % field "%p;field">
-<!ENTITY % group "%p;group">
-<!ENTITY % all "%p;all">
-<!ENTITY % choice "%p;choice">
-<!ENTITY % sequence "%p;sequence">
-<!ENTITY % any "%p;any">
-<!ENTITY % anyAttribute "%p;anyAttribute">
-<!ENTITY % attribute "%p;attribute">
-<!ENTITY % attributeGroup "%p;attributeGroup">
-<!ENTITY % include "%p;include">
-<!ENTITY % import "%p;import">
-<!ENTITY % notation "%p;notation">
-
-<!-- Customisation entities for the ATTLIST of each element type.
-     Define one of these if your schema takes advantage of the
-     anyAttribute='##other' in the schema for schemas -->
-
-<!ENTITY % schemaAttrs ''>
-<!ENTITY % complexTypeAttrs ''>
-<!ENTITY % elementAttrs ''>
-<!ENTITY % groupAttrs ''>
-<!ENTITY % allAttrs ''>
-<!ENTITY % choiceAttrs ''>
-<!ENTITY % sequenceAttrs ''>
-<!ENTITY % anyAttrs ''>
-<!ENTITY % anyAttributeAttrs ''>
-<!ENTITY % attributeAttrs ''>
-<!ENTITY % attributeGroupAttrs ''>
-<!ENTITY % uniqueAttrs ''>
-<!ENTITY % keyAttrs ''>
-<!ENTITY % keyrefAttrs ''>
-<!ENTITY % includeAttrs ''>
-<!ENTITY % importAttrs ''>
-<!ENTITY % notationAttrs ''>
-
-<!ENTITY % complexDerivationChoice "(extension|restriction)">
-<!ENTITY % complexDerivationSet "CDATA">
-      <!-- #all or space-separated list drawn from derivationChoice -->
-<!ENTITY % blockSet "CDATA">
-      <!-- #all or space-separated list drawn from
-                      derivationChoice + 'equivClass' -->
-
-<!ENTITY % mgs '%all; | %choice; | %sequence;'>
-<!ENTITY % cs '%choice; | %sequence;'>
-<!ENTITY % formValues '(qualified|unqualified)'>
-
-<!-- the duplication below is to produce an unambiguous content model
-     which allows annotation everywhere -->
-<!ELEMENT %schema; ((%include; | %import; | %annotation;)*,
-                    (%simpleType; | %complexType;
-                     | %element; | %attribute;
-                     | %attributeGroup; | %group;
-                     | %notation; ),
-                    (%annotation;
-                     | %simpleType; | %complexType;
-                     | %element; | %attribute;
-                     | %attributeGroup; | %group;
-                     | %notation; )* )>
-<!ATTLIST %schema;
-   targetNamespace      %URIref;               #IMPLIED
-   version              CDATA                  #IMPLIED
-   %nds;                %URIref;               #FIXED '&XMLSchemaNS;'
-   finalDefault         %complexDerivationSet; ''
-   blockDefault         %blockSet;             ''
-   id                   ID                     #IMPLIED
-   elementFormDefault   %formValues;           'unqualified'
-   attributeFormDefault %formValues;           'unqualified'
-   %schemaAttrs;>
-<!-- Note the xmlns declaration is NOT in the Schema for Schemas,
-     because at the Infoset level where schemas operate,
-     xmlns(:prefix) is NOT an attribute! -->
- 
-<!-- The id attribute here and below is for use in external references
-     from non-schemas using simple fragment identifiers.
-     It is NOT used for schema-to-schema reference, internal or
-     external. -->
-
-<!-- a type is a named content type specification which allows attribute
-     declarations-->
-<!-- -->
-
-<!ELEMENT %complexType; ((%annotation;)?,
-                 ((%facet;)*|
-                  ((%element;| %mgs; | %group; | %any;)*,
-                   (%attribute;| %attributeGroup;)*,
-                   (%anyAttribute;)?)))>
-
-<!ATTLIST %complexType;
-          name      %NCName;                        #IMPLIED
-          id        ID                              #IMPLIED
-          content   (textOnly|mixed|elementOnly|empty) #IMPLIED
-          abstract  %boolean;                       'false'
-          final     %complexDerivationSet;          ''
-          block     %complexDerivationSet;          ''
-          derivedBy %complexDerivationChoice;       #IMPLIED 
-          base      %QName;                         #IMPLIED
-          %complexTypeAttrs;>
-
-<!-- facets only if derivedBy='restriction' -->
-<!-- (element|group|any) only if content=mixed or =elementOnly
-     and no base at all, i.e. a root type, or base is a complex type -->
-<!-- content defaults to base's if there is a complex base,
-     textonly if there's a simple base,
-     'mixed' if no base (because that's the urType's content)
-             and no content daughters,
-     'elementOnly' otherwise --> 
-<!-- should we replace content='empty' with content='elementOnly'
-     final='#all' plus no content? -->
-
-<!-- If one top-level group, that IS the content model, otherwise
-     an implicit group obtains.
-     This is
-       <sequence minOccurs='1' maxOccurs='1'>
-     unless content='mixed', in which case it's
-       <choice minOccurs='0' maxOccurs='unbounded'> -->
-
-<!-- If anyAttribute appears in one or more referenced attributeGroups
-     and/or explicitly, the intersection of the permissions is used -->
-
-<!-- A text-only type with no attributes differs from a datatype with
-     the same base qualified the same way in regard to the impact on
-     attributes of anyAttribute -->
-
-<!-- an element is declared by either:
- a name and a type (either nested or referenced via the type attribute)
-or:
- a ref to an existing element declaration -->
-
-<!ELEMENT %element; ((%annotation;)?, (%complexType;| %simpleType;)?,
-                     (%unique; | %key; | %keyref;)*)>
-<!-- simpleType or complexType only if no type|ref attribute -->
-<!-- ref not allowed at top level -->
-<!ATTLIST %element;
-            name        %NCName;               #IMPLIED
-            id          ID                     #IMPLIED
-            ref         %QName;                #IMPLIED
-            type        %QName;                #IMPLIED
-            minOccurs   %nonNegativeInteger;   '1'
-            maxOccurs   CDATA                  #IMPLIED
-            nullable    %boolean;              'false'
-            equivClass  %QName;                #IMPLIED
-            abstract    %boolean;              'false'
-            final       %complexDerivationSet; ''
-            block       %blockSet;             ''
-            default     CDATA                  #IMPLIED
-            fixed       CDATA                  #IMPLIED
-            form        %formValues;           #IMPLIED
-            %elementAttrs;>
-<!-- type and ref are mutually exclusive.
-     name and ref are mutually exculsive, one is required -->
-<!-- In the absence of type AND ref, type defaults to type of
-     equivClass, if any, else the ur-type, i.e. unconstrained -->
-<!-- maxOccurs defaults to 1 or minOccurs, whichever is greater -->
-<!-- default and fixed are mutually exclusive -->
-
-<!ELEMENT %group; (%mgs;)?>
-<!ATTLIST %group; 
-          name        %NCName;               #IMPLIED
-          ref         %QName;                #IMPLIED
-          minOccurs   %nonNegativeInteger;   '1'
-          maxOccurs   CDATA                  #IMPLIED
-          id          ID                     #IMPLIED
-          %groupAttrs;>
-
-<!ELEMENT %all; ((%annotation;)?, (%element;| %group;| %cs; | %any;)*)>
-<!ATTLIST %all;
-          minOccurs   %nonNegativeInteger;   '1'
-          maxOccurs   CDATA                  #IMPLIED
-          id          ID                     #IMPLIED
-          %allAttrs;>
-
-<!ELEMENT %choice; ((%annotation;)?, (%element;| %group;| %cs; | %any;)*)>
-<!ATTLIST %choice;
-          minOccurs   %nonNegativeInteger;   '1'
-          maxOccurs   CDATA                  #IMPLIED
-          id          ID                     #IMPLIED
-          %choiceAttrs;>
-
-<!ELEMENT %sequence; ((%annotation;)?, (%element;| %group;| %cs; | %any;)*)>
-<!ATTLIST %sequence;
-          minOccurs   %nonNegativeInteger;   '1'
-          maxOccurs   CDATA                  #IMPLIED
-          id          ID                     #IMPLIED
-          %sequenceAttrs;>
-
-<!-- an anonymous grouping in a model, or
-     a top-level named group definition, or a reference to same -->
-
-<!-- Note that if order is 'all', group is not allowed inside.
-     If order is 'all' THIS group must be alone (or referenced alone) at
-     the top level of a content model -->
-<!-- If order is 'all', minOccurs==maxOccurs==1 on element/any inside -->
-<!-- Should allow minOccurs=0 inside order='all' . . . -->
-
-<!ELEMENT %any; (%annotation;)?>
-<!ATTLIST %any;
-            namespace       CDATA                  '##any'
-            processContents (skip|lax|strict)      'strict'
-            minOccurs       %nonNegativeInteger;   '1'
-            maxOccurs       CDATA                  #IMPLIED
-            %anyAttrs;>
-
-<!-- namespace is interpreted as follows:
-                  ##any      - - any non-conflicting WFXML at all
-
-                  ##other    - - any non-conflicting WFXML from namespace other
-                                  than targetNamespace
-
-                  ##local    - - any unqualified non-conflicting WFXML/attribute
-                  one or     - - any non-conflicting WFXML from
-                  more URI        the listed namespaces
-                  references
-
-                  ##targetNamespace may appear in the above list, with the
-                   obvious meaning -->
-
-<!ELEMENT %anyAttribute; (%annotation;)?>
-<!ATTLIST %anyAttribute;
-            namespace    CDATA   '##any'
-            %anyAttributeAttrs;>
-<!-- namespace is interpreted as for 'any' above -->
-
-<!-- simpleType only if no type|ref attribute -->
-<!-- ref not allowed at top level, name iff at top level -->
-<!ELEMENT %attribute; ((%annotation;)?, (%simpleType;)?)>
-<!ATTLIST %attribute;
-          name      %NCName;      #IMPLIED
-          id        ID            #IMPLIED
-          ref       %QName;       #IMPLIED
-          type      %QName;       #IMPLIED
-          use       (prohibited|optional|required|fixed|default) #IMPLIED
-          value     CDATA         #IMPLIED
-          form      %formValues;  #IMPLIED
-          %attributeAttrs;>
-<!-- type and ref are mutually exclusive.
-     name and ref are mutually exculsive, one is required -->
-<!-- value only if use is fixed, required or default, or name -->
-<!-- name and use are mutually exclusive -->
-<!-- default for use is optional when nested, none otherwise -->
-<!-- type attr and simpleType content are mutually exclusive -->
-
-<!-- an attributeGroup is a named collection of attribute decls, or a
-     reference thereto -->
-<!ELEMENT %attributeGroup; ((%annotation;)?,
-                       (%attribute; | %attributeGroup;)*,
-                       (%anyAttribute;)?) >
-<!ATTLIST %attributeGroup;
-                 name       %NCName;       #IMPLIED
-                 id         ID             #IMPLIED
-                 ref        %QName;        #IMPLIED
-                 %attributeGroupAttrs;>
-
-<!-- ref iff no content, no name.  ref iff not top level -->
-
-<!-- better reference mechanisms -->
-<!ELEMENT %unique; ((%annotation;)?, %selector;, (%field;)+)>
-<!ATTLIST %unique; name     %NCName;       #REQUIRED
-                   id       ID             #IMPLIED
-                   %uniqueAttrs;>
-
-<!ELEMENT %key;    ((%annotation;)?, %selector;, (%field;)+)>
-<!ATTLIST %key;    name     %NCName;       #REQUIRED
-                   id       ID             #IMPLIED
-                   %keyAttrs;>
-
-<!ELEMENT %keyref; ((%annotation;)?, %selector;, (%field;)+)>
-<!ATTLIST %keyref;
-                   name     %NCName;       #REQUIRED
-                   id       ID             #IMPLIED
-                   refer    %QName;        #REQUIRED
-                   %keyrefAttrs;>
-
-<!ELEMENT %selector; (#PCDATA)>
-<!ELEMENT %field; (#PCDATA)>
-
-<!-- Schema combination mechanisms -->
-<!ELEMENT %include; (%annotation;)?>
-<!ATTLIST %include; schemaLocation %URIref; #REQUIRED
-                    %includeAttrs;>
-
-<!ELEMENT %import; (%annotation;)?>
-<!ATTLIST %import; namespace      %URIref; #IMPLIED
-                   schemaLocation %URIref; #IMPLIED
-                   %importAttrs;>
-
-<!ELEMENT %notation; (%annotation;)?>
-<!ATTLIST %notation;
-                 name        %NCName;    #REQUIRED
-                 id          ID          #IMPLIED
-                 public      CDATA       #REQUIRED
-                 system      %URIref;    #IMPLIED
-                 %notationAttrs;>
-
-<!NOTATION XMLSchemaStructures PUBLIC 'structures'
-           '&XSP1.URI;.xsd' >
-<!NOTATION XML PUBLIC 'REC-xml-1998-0210'
-               'http://www.w3.org/TR/1998/REC-xml-19980210' >
-
-
diff --git a/src/org/apache/xerces/validators/schema/versionInfo.ent b/src/org/apache/xerces/validators/schema/versionInfo.ent
deleted file mode 100644
index f6666b2..0000000
--- a/src/org/apache/xerces/validators/schema/versionInfo.ent
+++ /dev/null
@@ -1,40 +0,0 @@
-<!-- Path and date information for XML Schema recommendation documents -->
-<!-- $Id$ -->
-<!ENTITY draft.year "2000">
-<!ENTITY draft.YY "2000">
-<!ENTITY draft.month "April">
-<!ENTITY draft.MM "04">
-<!ENTITY draft.base "http://www.w3.org/XML/Group/xmlschema-current">
-<!-- "file:///d:/henry/xmlschema"> -->
-<!ENTITY % WD-XSP1 "structures">
-<!ENTITY draft.day "2">
-<!ENTITY draft.DD "02">
-<!ENTITY % WD-XSP1d '"%WD-XSP1;"'>
-<!ENTITY WD-XSP1 %WD-XSP1d;>
-<!ENTITY XSP0.base "&draft.base;/structures">
-<!ENTITY XSP1.base "&draft.base;/structures">
-<!ENTITY XSP1.URI "&XSP1.base;/structures">
-<!ENTITY WD-XSP2 "datatypes">
-<!ENTITY XSP2.base "&draft.base;/datatypes">
-<!ENTITY XSP2.URI "&XSP2.base;/datatypes">
-<!ENTITY XMLSchemaNS "http://www.w3.org/1999/XMLSchema">
-<!ENTITY XMLSchemaInstanceNS "http://www.w3.org/1999/XMLSchema/instance">
-<!ENTITY % reldatadtd "'../datatypes/datatypes.dtd'">
-
-<!ENTITY % schemaProper '"http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/structures.dtd"'>
-<!ENTITY schemaProper SYSTEM %schemaProper; NDATA xmlschema>
-
-<!ENTITY % datatypeSchemaProper '"http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/datatypes.dtd"'>
-<!ENTITY datatypeSchemaProper SYSTEM %datatypeSchemaProper; NDATA xmlschema>
-<!ENTITY % datatypeSchemaDump '"datatypes.xsd,dmp"'>
-<!ENTITY datatypeSchemaDump SYSTEM %datatypeSchemaDump; NDATA xmlschema>
-<!ENTITY % builtinsSchemaProper '"builtins.xsd"'>
-<!ENTITY builtinsSchemaProper SYSTEM %builtinsSchemaProper; NDATA xmlschema>
-<!ENTITY % schemaDump '"structures/structures.xsd,dmp"'>
-<!ENTITY schemaDump SYSTEM %schemaDump; NDATA xmlschema>
-<!ENTITY % schemaExample '"structures/example.xsd,dmp"'>
-<!ENTITY schemaExample SYSTEM %schemaExample; NDATA xmlschema>
-<!NOTATION xmlschema PUBLIC 'structures' '&XSP1.URI;.xsd' >
-<!ENTITY expo '<bibref ref="bib-expo"/>'>
-
-
diff --git a/src/org/apache/xml/Makefile b/src/org/apache/xml/Makefile
deleted file mode 100644
index 85240fc..0000000
--- a/src/org/apache/xml/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# Makefile for directory ./org/apache/xml
-
-TARGETS=
-
-
-DIRS = serialize
-
-TOP = ../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xml/serialize/BaseMarkupSerializer.java b/src/org/apache/xml/serialize/BaseMarkupSerializer.java
deleted file mode 100644
index 42e3281..0000000
--- a/src/org/apache/xml/serialize/BaseMarkupSerializer.java
+++ /dev/null
@@ -1,1441 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-// Aug 25, 2000:
-//   Fixed processing instruction printing inside element content
-//   to not escape content. Reported by Mikael Staldal
-//   <d96-mst@d.kth.se>
-// Aug 25, 2000:
-//   Added ability to omit comments.
-//   Contributed by Anupam Bagchi <abagchi@jtcsv.com>
-// Aug 26, 2000:
-//   Fixed bug in newline handling when preserving spaces.
-//   Contributed by Mike Dusseault <mdusseault@home.com>
-// Aug 29, 2000:
-//   Fixed state.unescaped not being set to false when
-//   entering element state.
-//   Reported by Lowell Vaughn <lvaughn@agillion.com>
-
-
-package org.apache.xml.serialize;
-
-
-import java.io.Writer;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.Vector;
-import java.util.Hashtable;
-import java.util.StringTokenizer;
-
-import org.w3c.dom.*;
-import org.xml.sax.DocumentHandler;
-import org.xml.sax.DTDHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.Attributes;
-import org.xml.sax.ext.LexicalHandler;
-import org.xml.sax.ext.DeclHandler;
-
-
-/**
- * Base class for a serializer supporting both DOM and SAX pretty
- * serializing of XML/HTML/XHTML documents. Derives classes perform
- * the method-specific serializing, this class provides the common
- * serializing mechanisms.
- * <p>
- * The serializer must be initialized with the proper writer and
- * output format before it can be used by calling {@link #init}.
- * The serializer can be reused any number of times, but cannot
- * be used concurrently by two threads.
- * <p>
- * If an output stream is used, the encoding is taken from the
- * output format (defaults to <tt>UTF-8</tt>). If a writer is
- * used, make sure the writer uses the same encoding (if applies)
- * as specified in the output format.
- * <p>
- * The serializer supports both DOM and SAX. DOM serializing is done
- * by calling {@link #serialize} and SAX serializing is done by firing
- * SAX events and using the serializer as a document handler.
- * This also applies to derived class.
- * <p>
- * If an I/O exception occurs while serializing, the serializer
- * will not throw an exception directly, but only throw it
- * at the end of serializing (either DOM or SAX's {@link
- * org.xml.sax.DocumentHandler#endDocument}.
- * <p>
- * For elements that are not specified as whitespace preserving,
- * the serializer will potentially break long text lines at space
- * boundaries, indent lines, and serialize elements on separate
- * lines. Line terminators will be regarded as spaces, and
- * spaces at beginning of line will be stripped.
- * <p>
- * When indenting, the serializer is capable of detecting seemingly
- * element content, and serializing these elements indented on separate
- * lines. An element is serialized indented when it is the first or
- * last child of an element, or immediate following or preceding
- * another element.
- *
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- * @see Serializer
- * @see DOMSerializer
- */
-public abstract class BaseMarkupSerializer
-    implements ContentHandler, DocumentHandler, LexicalHandler,
-               DTDHandler, DeclHandler, DOMSerializer, Serializer
-{
-
-
-    /**
-     * Identifies the last printable character in the Unicode range
-     * that is supported by the encoding used with this serializer.
-     * For 8-bit encodings this will be either 0x7E or 0xFF.
-     * For 16-bit encodings this will be 0xFFFF. Characters that are
-     * not printable will be escaped using character references.
-     */
-    private int              _lastPrintable = 0x7E;
-
-
-    /**
-     * Holds array of all element states that have been entered.
-     * The array is automatically resized. When leaving an element,
-     * it's state is not removed but reused when later returning
-     * to the same nesting level.
-     */
-    private ElementState[]  _elementStates;
-
-
-    /**
-     * The index of the next state to place in the array,
-     * or one plus the index of the current state. When zero,
-     * we are in no state.
-     */
-    private int             _elementStateCount;
-
-
-    /**
-     * Vector holding comments and PIs that come before the root
-     * element (even after it), see {@link #serializePreRoot}.
-     */
-    private Vector          _preRoot;
-
-
-    /**
-     * If the document has been started (header serialized), this
-     * flag is set to true so it's not started twice.
-     */
-    protected boolean       _started;
-
-
-    /**
-     * True if the serializer has been prepared. This flag is set
-     * to false when the serializer is reset prior to using it,
-     * and to true after it has been prepared for usage.
-     */
-    private boolean         _prepared;
-
-
-    /**
-     * Association between namespace URIs (keys) and prefixes (values).
-     * Accumulated here prior to starting an element and placing this
-     * list in the element state.
-     */
-    protected Hashtable     _prefixes;
-
-
-    /**
-     * The system identifier of the document type, if known.
-     */
-    protected String        _docTypePublicId;
-
-
-    /**
-     * The system identifier of the document type, if known.
-     */
-    protected String        _docTypeSystemId;
-
-
-    /**
-     * The output format associated with this serializer. This will never
-     * be a null reference. If no format was passed to the constructor,
-     * the default one for this document type will be used. The format
-     * object is never changed by the serializer.
-     */
-    protected OutputFormat   _format;
-
-
-    /**
-     * The printer used for printing text parts.
-     */
-    protected Printer       _printer;
-
-
-    /**
-     * True if indenting printer.
-     */
-    protected boolean       _indenting;
-
-
-    /**
-     * The underlying writer.
-     */
-    private Writer          _writer;
-
-
-    /**
-     * The output stream.
-     */
-    private OutputStream    _output;
-
-
-    //--------------------------------//
-    // Constructor and initialization //
-    //--------------------------------//
-
-
-    /**
-     * Protected constructor can only be used by derived class.
-     * Must initialize the serializer before serializing any document,
-     * see {@link #init}.
-     */
-    protected BaseMarkupSerializer( OutputFormat format )
-    {
-        int i;
-
-        _elementStates = new ElementState[ 10 ];
-        for ( i = 0 ; i < _elementStates.length ; ++i )
-            _elementStates[ i ] = new ElementState();
-        _format = format;
-    }
-
-
-    public DocumentHandler asDocumentHandler()
-        throws IOException
-    {
-        prepare();
-        return this;
-    }
-
-
-    public ContentHandler asContentHandler()
-        throws IOException
-    {
-        prepare();
-        return this;
-    }
-
-
-    public DOMSerializer asDOMSerializer()
-        throws IOException
-    {
-        prepare();
-        return this;
-    }
-
-
-    public void setOutputByteStream( OutputStream output )
-    {
-        String encoding;
-
-        if ( output == null )
-            throw new NullPointerException( "SER001 Argument 'output' is null." );
-        _output = output;
-        _writer = null;
-        reset();
-    }
-
-
-    public void setOutputCharStream( Writer writer )
-    {
-        if ( writer == null )
-            throw new NullPointerException( "SER001 Argument 'writer' is null." );
-        _writer = writer;
-        _output = null;
-        reset();
-    }
-
-
-    public void setOutputFormat( OutputFormat format )
-    {
-        if ( format == null )
-            throw new NullPointerException( "SER001 Argument 'format' is null." );
-        _format = format;
-        reset();
-    }
-
-
-    public boolean reset()
-    {
-        if ( _elementStateCount > 1 )
-            throw new IllegalStateException( "Serializer reset in the middle of serialization" );
-        _prepared = false;
-        return true;
-    }
-
-
-    protected void prepare()
-        throws IOException
-    {
-        if ( _prepared )
-            return;
-
-        if ( _writer == null && _output == null )
-            throw new IOException( "SER002 No writer supplied for serializer" );
-        // If the output stream has been set, use it to construct
-        // the writer. It is possible that the serializer has been
-        // reused with the same output stream and different encoding.
-        if ( _output != null ) {
-            if ( _format.getEncoding() == null )
-                _writer = new OutputStreamWriter( _output );
-            else
-                _writer = Encodings.getWriter( _output, _format.getEncoding() );
-        }
-        // Determine the last printable character.
-        if ( _format.getEncoding() == null )
-            _lastPrintable = Encodings.getLastPrintable();
-        else
-            _lastPrintable = Encodings.getLastPrintable( _format.getEncoding() );
-
-        if ( _format.getIndenting() ) {
-            _indenting = true;
-            _printer = new IndentPrinter( _writer, _format );
-        } else {
-            _indenting = false;
-            _printer = new Printer( _writer, _format );
-        }
-
-        ElementState state;
-
-        _elementStateCount = 0;
-        state = _elementStates[ 0 ];
-        state.namespaceURI = null;
-        state.localName = null;
-        state.rawName = null;
-        state.preserveSpace = _format.getPreserveSpace();
-        state.empty = true;
-        state.afterElement = false;
-        state.doCData = state.inCData = false;
-        state.prefixes = null;
-
-        _docTypePublicId = _format.getDoctypePublic();
-        _docTypeSystemId = _format.getDoctypeSystem();
-        _started = false;
-        _prepared = true;
-    }
-
-
-
-    //----------------------------------//
-    // DOM document serializing methods //
-    //----------------------------------//
-
-
-    /**
-     * Serializes the DOM element using the previously specified
-     * writer and output format. Throws an exception only if
-     * an I/O exception occured while serializing.
-     *
-     * @param elem The element to serialize
-     * @throws IOException An I/O exception occured while
-     *   serializing
-     */
-    public void serialize( Element elem )
-        throws IOException
-    {
-        prepare();
-        serializeNode( elem );
-        _printer.flush();
-        if ( _printer.getException() != null )
-            throw _printer.getException();
-    }
-
-
-    /**
-     * Serializes the DOM document fragmnt using the previously specified
-     * writer and output format. Throws an exception only if
-     * an I/O exception occured while serializing.
-     *
-     * @param elem The element to serialize
-     * @throws IOException An I/O exception occured while
-     *   serializing
-     */
-    public void serialize( DocumentFragment frag )
-        throws IOException
-    {
-        prepare();
-        serializeNode( frag );
-        _printer.flush();
-        if ( _printer.getException() != null )
-            throw _printer.getException();
-    }
-
-
-    /**
-     * Serializes the DOM document using the previously specified
-     * writer and output format. Throws an exception only if
-     * an I/O exception occured while serializing.
-     *
-     * @param doc The document to serialize
-     * @throws IOException An I/O exception occured while
-     *   serializing
-     */
-    public void serialize( Document doc )
-        throws IOException
-    {
-        prepare();
-        serializeNode( doc );
-        serializePreRoot();
-        _printer.flush();
-        if ( _printer.getException() != null )
-            throw _printer.getException();
-    }
-
-
-    //------------------------------------------//
-    // SAX document handler serializing methods //
-    //------------------------------------------//
-
-
-    public void startDocument()
-        throws SAXException
-    {
-        try {
-            prepare();
-        } catch ( IOException except ) {
-            throw new SAXException( except.toString() );
-        }
-        // Nothing to do here. All the magic happens in startDocument(String)
-    }
-    
-    
-    public void characters( char[] chars, int start, int length )
-    {
-        ElementState state;
-
-        state = content();
-        // Check if text should be print as CDATA section or unescaped
-        // based on elements listed in the output format (the element
-        // state) or whether we are inside a CDATA section or entity.
-
-        if ( state.inCData || state.doCData ) {
-            int          saveIndent;
-
-            // Print a CDATA section. The text is not escaped, but ']]>'
-            // appearing in the code must be identified and dealt with.
-            // The contents of a text node is considered space preserving.
-            if ( ! state.inCData ) {
-                _printer.printText( "<![CDATA[" );
-                state.inCData = true;
-            }
-            saveIndent = _printer.getNextIndent();
-            _printer.setNextIndent( 0 );
-            for ( int index = 0 ; index < length ; ++index ) {
-                if ( index + 2 < length && chars[ index ] == ']' &&
-                     chars[ index + 1 ] == ']' && chars[ index + 2 ] == '>' ) {
-
-                    printText( chars, start, index + 2, true, true );
-                    _printer.printText( "]]><![CDATA[" );
-                    start += index + 2;
-                    length -= index + 2;
-                    index = 0;
-                }
-            }
-            if ( length > 0 )
-                printText( chars, start, length, true, true );
-            _printer.setNextIndent( saveIndent );
-
-        } else {
-
-            int saveIndent;
-
-            if ( state.preserveSpace ) {
-                // If preserving space then hold of indentation so no
-                // excessive spaces are printed at line breaks, escape
-                // the text content without replacing spaces and print
-                // the text breaking only at line breaks.
-                saveIndent = _printer.getNextIndent();
-                _printer.setNextIndent( 0 );
-                printText( chars, start, length, true, state.unescaped );
-                _printer.setNextIndent( saveIndent );
-            } else {
-                printText( chars, start, length, false, state.unescaped );
-            }
-        }
-    }
-
-
-    public void ignorableWhitespace( char[] chars, int start, int length )
-    {
-        int i;
-
-        content();
-
-        // Print ignorable whitespaces only when indenting, after
-        // all they are indentation. Cancel the indentation to
-        // not indent twice.
-        if ( _indenting ) {
-            _printer.setThisIndent( 0 );
-            for ( i = start ; length-- > 0 ; ++i )
-                _printer.printText( chars[ i ] );
-        }
-    }
-
-
-    public void processingInstruction( String target, String code )
-    {
-        int          index;
-        StringBuffer buffer;
-        ElementState state;
-
-        state = content();
-        buffer = new StringBuffer( 40 );
-
-        // Create the processing instruction textual representation.
-        // Make sure we don't have '?>' inside either target or code.
-        index = target.indexOf( "?>" );
-        if ( index >= 0 )
-            buffer.append( "<?" ).append( target.substring( 0, index ) );
-        else
-            buffer.append( "<?" ).append( target );
-        if ( code != null ) {
-            buffer.append( ' ' );
-            index = code.indexOf( "?>" );
-            if ( index >= 0 )
-                buffer.append( code.substring( 0, index ) );
-            else
-                buffer.append( code );
-        }
-        buffer.append( "?>" );
-
-        // If before the root element (or after it), do not print
-        // the PI directly but place it in the pre-root vector.
-        if ( isDocumentState() ) {
-            if ( _preRoot == null )
-                _preRoot = new Vector();
-            _preRoot.addElement( buffer.toString() );
-        } else {
-            _printer.indent();
-            printText( buffer.toString(), true, true );
-            _printer.unindent();
-        }
-    }
-
-
-    public void comment( char[] chars, int start, int length )
-    {
-        comment( new String( chars, start, length ) );
-    }
-
-
-    public void comment( String text )
-    {
-        StringBuffer buffer;
-        int          index;
-        ElementState state;
-        
-        if ( _format.getOmitComments() )
-            return;
-
-        state  = content();
-        buffer = new StringBuffer( 40 );
-        // Create the processing comment textual representation.
-        // Make sure we don't have '-->' inside the comment.
-        index = text.indexOf( "-->" );
-        if ( index >= 0 )
-            buffer.append( "<!--" ).append( text.substring( 0, index ) ).append( "-->" );
-        else
-            buffer.append( "<!--" ).append( text ).append( "-->" );
-
-        // If before the root element (or after it), do not print
-        // the comment directly but place it in the pre-root vector.
-        if ( isDocumentState() ) {
-            if ( _preRoot == null )
-                _preRoot = new Vector();
-            _preRoot.addElement( buffer.toString() );
-        } else {
-            _printer.indent();
-            printText( buffer.toString(), false, true );
-            _printer.unindent();
-        }
-    }
-
-
-    public void startCDATA()
-    {
-        ElementState state;
-
-        state = getElementState();
-        state.doCData = true;
-    }
-
-
-    public void endCDATA()
-    {
-        ElementState state;
-
-        state = getElementState();
-        state.doCData = false;
-    }
-
-
-    public void startNonEscaping()
-    {
-        ElementState state;
-
-        state = getElementState();
-        state.unescaped = true;
-    }
-
-
-    public void endNonEscaping()
-    {
-        ElementState state;
-
-        state = getElementState();
-        state.unescaped = false;
-    }
-
-
-    public void startPreserving()
-    {
-        ElementState state;
-
-        state = getElementState();
-        state.preserveSpace = true;
-    }
-
-
-    public void endPreserving()
-    {
-        ElementState state;
-
-        state = getElementState();
-        state.preserveSpace = false;
-    }
-
-
-    /**
-     * Called at the end of the document to wrap it up.
-     * Will flush the output stream and throw an exception
-     * if any I/O error occured while serializing.
-     *
-     * @throws SAXException An I/O exception occured during
-     *  serializing
-     */
-    public void endDocument()
-        throws SAXException
-    {
-        // Print all the elements accumulated outside of
-        // the root element.
-        serializePreRoot();
-        // Flush the output, this is necessary for buffered output.
-        _printer.flush();
-        // If an exception was thrown during serializing, this would
-        // be the best time to report it.
-        if ( _printer.getException() != null )
-            throw new SAXException( _printer.getException() );
-    }
-
-
-    public void startEntity( String name )
-    {
-        // ???
-    }
-
-
-    public void endEntity( String name )
-    {
-        // ???
-    }
-
-
-    public void setDocumentLocator( Locator locator )
-    {
-        // Nothing to do
-    }
-
-
-    //-----------------------------------------//
-    // SAX content handler serializing methods //
-    //-----------------------------------------//
-
-
-    public void skippedEntity ( String name )
-        throws SAXException
-    {
-        endCDATA();
-        content();
-        _printer.printText( '&' );
-        _printer.printText( name );
-        _printer.printText( ';' );
-    }
-
-
-    public void startPrefixMapping( String prefix, String uri )
-        throws SAXException
-    {
-        if ( _prefixes == null )
-            _prefixes = new Hashtable();
-        _prefixes.put( uri, prefix == null ? "" : prefix );
-    }
-
-
-    public void endPrefixMapping( String prefix )
-        throws SAXException
-    {
-    }
-
-
-    //------------------------------------------//
-    // SAX DTD/Decl handler serializing methods //
-    //------------------------------------------//
-
-
-    public void startDTD( String name, String publicId, String systemId )
-    {
-        _printer.enterDTD();
-        _docTypePublicId = publicId;
-        _docTypeSystemId = systemId;
-    }
-
-
-    public void endDTD()
-    {
-        // Nothing to do here, all the magic occurs in startDocument(String).
-    }
-
-
-    public void elementDecl( String name, String model )
-    {
-        _printer.enterDTD();
-        _printer.printText( "<!ELEMENT " );
-        _printer.printText( name );
-        _printer.printText( ' ' );
-        _printer.printText( model );
-        _printer.printText( '>' );
-        if ( _indenting )
-            _printer.breakLine();
-    }
-
-
-    public void attributeDecl( String eName, String aName, String type,
-                               String valueDefault, String value )
-    {
-        _printer.enterDTD();
-        _printer.printText( "<!ATTLIST " );
-        _printer.printText( eName );
-        _printer.printText( ' ' );
-        _printer.printText( aName );
-        _printer.printText( ' ' );
-        _printer.printText( type );
-        if ( valueDefault != null ) {
-            _printer.printText( ' ' );
-            _printer.printText( valueDefault );
-        }
-        if ( value != null ) {
-            _printer.printText( " \"" );
-            printEscaped( value );
-            _printer.printText( '"' );
-        }
-        _printer.printText( '>' );
-        if ( _indenting )
-            _printer.breakLine();
-    }
-
-
-    public void internalEntityDecl( String name, String value )
-    {
-        _printer.enterDTD();
-        _printer.printText( "<!ENTITY " );
-        _printer.printText( name );
-        _printer.printText( " \"" );
-        printEscaped( value );
-        _printer.printText( "\">" );
-        if ( _indenting )
-            _printer.breakLine();
-    }
-
-
-    public void externalEntityDecl( String name, String publicId, String systemId )
-    {
-        _printer.enterDTD();
-        unparsedEntityDecl( name, publicId, systemId, null );
-    }
-
-
-    public void unparsedEntityDecl( String name, String publicId,
-                                    String systemId, String notationName )
-    {
-        _printer.enterDTD();
-        if ( publicId == null ) {
-            _printer.printText( "<!ENTITY " );
-            _printer.printText( name );
-            _printer.printText( " SYSTEM " );
-            printDoctypeURL( systemId );
-        } else {
-            _printer.printText( "<!ENTITY " );
-            _printer.printText( name );
-            _printer.printText( " PUBLIC " );
-            printDoctypeURL( publicId );
-            _printer.printText( ' ' );
-            printDoctypeURL( systemId );
-        }
-        if ( notationName != null ) {
-            _printer.printText( " NDATA " );
-            _printer.printText( notationName );
-        }
-        _printer.printText( '>' );
-        if ( _indenting )
-            _printer.breakLine();
-    }
-
-
-    public void notationDecl( String name, String publicId, String systemId )
-    {
-        _printer.enterDTD();
-        if ( publicId != null ) {
-            _printer.printText( "<!NOTATION " );
-            _printer.printText( name );
-            _printer.printText( " PUBLIC " );
-            printDoctypeURL( publicId );
-            if ( systemId != null ) {
-                _printer.printText( ' ' );
-                printDoctypeURL( systemId );
-            }
-        } else {
-            _printer.printText( "<!NOTATION " );
-            _printer.printText( name );
-            _printer.printText( " SYSTEM " );
-            printDoctypeURL( systemId );
-        }
-        _printer.printText( '>' );
-        if ( _indenting )
-            _printer.breakLine();
-    }
-
-
-    //------------------------------------------//
-    // Generic node serializing methods methods //
-    //------------------------------------------//
-
-
-    /**
-     * Serialize the DOM node. This method is shared across XML, HTML and XHTML
-     * serializers and the differences are masked out in a separate {@link
-     * #serializeElement}.
-     *
-     * @param node The node to serialize
-     * @see #serializeElement
-     */
-    protected void serializeNode( Node node )
-    {
-        // Based on the node type call the suitable SAX handler.
-        // Only comments entities and documents which are not
-        // handled by SAX are serialized directly.
-        switch ( node.getNodeType() ) {
-        case Node.TEXT_NODE : {
-            String text;
-
-            text = node.getNodeValue();
-            if ( text != null )
-                characters( node.getNodeValue() );
-            break;
-        }
-
-        case Node.CDATA_SECTION_NODE : {
-            String text;
-
-            text = node.getNodeValue();
-            if ( text != null ) {
-                startCDATA();
-                characters( node.getNodeValue() );
-                endCDATA();
-            }
-            break;
-        }
-
-        case Node.COMMENT_NODE : {
-            String text;
-
-            if ( ! _format.getOmitComments() ) {
-                text = node.getNodeValue();
-                if ( text != null )
-                    comment( node.getNodeValue() );
-            }
-            break;
-        }
-
-        case Node.ENTITY_REFERENCE_NODE : {
-            Node         child;
-
-            endCDATA();
-            content();
-            child = node.getFirstChild();
-            while ( child != null ) {
-                serializeNode( child );
-                child = child.getNextSibling();
-            }
-            break;
-        }
-
-        case Node.PROCESSING_INSTRUCTION_NODE :
-            processingInstruction( node.getNodeName(), node.getNodeValue() );
-            break;
-
-        case Node.ELEMENT_NODE :
-            serializeElement( (Element) node );
-            break;
-
-        case Node.DOCUMENT_NODE : {
-            DocumentType      docType;
-            DOMImplementation domImpl;
-            NamedNodeMap      map;
-            Entity            entity;
-            Notation          notation;
-            int               i;
-
-            // If there is a document type, use the SAX events to
-            // serialize it.
-            docType = ( (Document) node ).getDoctype();
-            if (docType != null) {
-                // DOM Level 2 (or higher)
-                domImpl = ( (Document) node ).getImplementation();
-                try {
-                    String internal;
-
-                    startDTD( docType.getName(), docType.getPublicId(), docType.getSystemId() );
-                    internal = docType.getInternalSubset();
-                    if ( internal != null && internal.length() > 0 )
-                        _printer.printText( internal );
-                    endDTD();
-                }
-                // DOM Level 1 -- does implementation have methods?
-                catch (NoSuchMethodError nsme) {
-                    Class docTypeClass = docType.getClass();
-
-                    String docTypePublicId = null;
-                    String docTypeSystemId = null;
-                    try {
-                        java.lang.reflect.Method getPublicId = docTypeClass.getMethod("getPublicId", null);
-                        if (getPublicId.getReturnType().equals(String.class)) {
-                            docTypePublicId = (String)getPublicId.invoke(docType, null);
-                        }
-                    }
-                    catch (Exception e) {
-                        // ignore
-                    }
-                    try {
-                        java.lang.reflect.Method getSystemId = docTypeClass.getMethod("getSystemId", null);
-                        if (getSystemId.getReturnType().equals(String.class)) {
-                            docTypeSystemId = (String)getSystemId.invoke(docType, null);
-                        }
-                    }
-                    catch (Exception e) {
-                        // ignore
-                    }
-                    startDTD( docType.getName(), docTypePublicId, docTypeSystemId);
-                    endDTD();
-                }
-            }
-            // !! Fall through
-        }
-        case Node.DOCUMENT_FRAGMENT_NODE : {
-            Node         child;
-
-            // By definition this will happen if the node is a document,
-            // document fragment, etc. Just serialize its contents. It will
-            // work well for other nodes that we do not know how to serialize.
-            child = node.getFirstChild();
-            while ( child != null ) {
-                serializeNode( child );
-                child = child.getNextSibling();
-            }
-            break;
-        }
-
-        default:
-            break;
-        }
-    }
-
-
-    /**
-     * Must be called by a method about to print any type of content.
-     * If the element was just opened, the opening tag is closed and
-     * will be matched to a closing tag. Returns the current element
-     * state with <tt>empty</tt> and <tt>afterElement</tt> set to false.
-     *
-     * @return The current element state
-     */
-    protected ElementState content()
-    {
-        ElementState state;
-
-        state = getElementState();
-        if ( ! isDocumentState() ) {
-            // Need to close CData section first
-            if ( state.inCData && ! state.doCData ) {
-                _printer.printText( "]]>" );
-                state.inCData = false;
-            }
-            // If this is the first content in the element,
-            // change the state to not-empty and close the
-            // opening element tag.
-            if ( state.empty ) {
-                _printer.printText( '>' );
-                state.empty = false;
-            }
-            // Except for one content type, all of them
-            // are not last element. That one content
-            // type will take care of itself.
-            state.afterElement = false;
-        }
-        return state;
-    }
-
-
-    /**
-     * Called to print the text contents in the prevailing element format.
-     * Since this method is capable of printing text as CDATA, it is used
-     * for that purpose as well. White space handling is determined by the
-     * current element state. In addition, the output format can dictate
-     * whether the text is printed as CDATA or unescaped.
-     *
-     * @param text The text to print
-     * @param unescaped True is should print unescaped
-     */
-    protected void characters( String text )
-    {
-        ElementState state;
-
-        state = content();
-        // Check if text should be print as CDATA section or unescaped
-        // based on elements listed in the output format (the element
-        // state) or whether we are inside a CDATA section or entity.
-
-        if ( state.inCData || state.doCData ) {
-            StringBuffer buffer;
-            int          index;
-            int          saveIndent;
-
-            // Print a CDATA section. The text is not escaped, but ']]>'
-            // appearing in the code must be identified and dealt with.
-            // The contents of a text node is considered space preserving.
-            buffer = new StringBuffer( text.length() );
-            if ( ! state.inCData ) {
-                buffer.append( "<![CDATA[" );
-                state.inCData = true;
-            }
-            index = text.indexOf( "]]>" );
-            while ( index >= 0 ) {
-                buffer.append( text.substring( 0, index + 2 ) ).append( "]]><![CDATA[" );
-                text = text.substring( index + 2 );
-                index = text.indexOf( "]]>" );
-            }
-            buffer.append( text );
-            saveIndent = _printer.getNextIndent();
-            _printer.setNextIndent( 0 );
-            printText( buffer.toString(), true, true );
-            _printer.setNextIndent( saveIndent );
-
-        } else {
-
-            int saveIndent;
-
-            if ( state.preserveSpace ) {
-                // If preserving space then hold of indentation so no
-                // excessive spaces are printed at line breaks, escape
-                // the text content without replacing spaces and print
-                // the text breaking only at line breaks.
-                saveIndent = _printer.getNextIndent();
-                _printer.setNextIndent( 0 );
-                printText( text, true, state.unescaped );
-                _printer.setNextIndent( saveIndent );
-            } else {
-                printText( text, false, state.unescaped );
-            }
-        }
-    }
-
-
-    /**
-     * Returns the suitable entity reference for this character value,
-     * or null if no such entity exists. Calling this method with <tt>'&amp;'</tt>
-     * will return <tt>"&amp;amp;"</tt>.
-     *
-     * @param ch Character value
-     * @return Character entity name, or null
-     */
-    protected abstract String getEntityRef( char ch );
-
-
-    /**
-     * Called to serializee the DOM element. The element is serialized based on
-     * the serializer's method (XML, HTML, XHTML).
-     *
-     * @param elem The element to serialize
-     */
-    protected abstract void serializeElement( Element elem );
-
-
-    /**
-     * Comments and PIs cannot be serialized before the root element,
-     * because the root element serializes the document type, which
-     * generally comes first. Instead such PIs and comments are
-     * accumulated inside a vector and serialized by calling this
-     * method. Will be called when the root element is serialized
-     * and when the document finished serializing.
-     */
-    protected void serializePreRoot()
-    {
-        int i;
-
-        if ( _preRoot != null ) {
-            for ( i = 0 ; i < _preRoot.size() ; ++i ) {
-                printText( (String) _preRoot.elementAt( i ), true, true );
-                _printer.breakLine();
-            }
-            _preRoot.removeAllElements();
-        }
-    }
-
-
-    //---------------------------------------------//
-    // Text pretty printing and formatting methods //
-    //---------------------------------------------//
-
-
-    /**
-     * Called to print additional text with whitespace handling.
-     * If spaces are preserved, the text is printed as if by calling
-     * {@link #printText(String)} with a call to {@link #breakLine}
-     * for each new line. If spaces are not preserved, the text is
-     * broken at space boundaries if longer than the line width;
-     * Multiple spaces are printed as such, but spaces at beginning
-     * of line are removed.
-     *
-     * @param text The text to print
-     * @param preserveSpace Space preserving flag
-     * @param unescaped Print unescaped
-     */
-    protected final void printText( char[] chars, int start, int length,
-                                    boolean preserveSpace, boolean unescaped )
-    {
-        int index;
-        char ch;
-
-        if ( preserveSpace ) {
-            // Preserving spaces: the text must print exactly as it is,
-            // without breaking when spaces appear in the text and without
-            // consolidating spaces. If a line terminator is used, a line
-            // break will occur.
-            while ( length-- > 0 ) {
-                ch = chars[ start ];
-                ++start;
-                if ( ch == '\n' || ch == '\r' || unescaped )
-                    _printer.printText( ch );
-                else
-                    printEscaped( ch );
-            }
-        } else {
-            // Not preserving spaces: print one part at a time, and
-            // use spaces between parts to break them into different
-            // lines. Spaces at beginning of line will be stripped
-            // by printing mechanism. Line terminator is treated
-            // no different than other text part.
-            while ( length-- > 0 ) {
-                ch = chars[ start ];
-                ++start;
-                if ( ch == ' ' || ch == '\f' || ch == '\t' || ch == '\n' || ch == '\r' )
-                    _printer.printSpace();
-                else if ( unescaped )
-                    _printer.printText( ch );
-                else
-                    printEscaped( ch );
-            }
-        }
-    }
-
-
-    protected final void printText( String text, boolean preserveSpace, boolean unescaped )
-    {
-        int index;
-        char ch;
-
-        if ( preserveSpace ) {
-            // Preserving spaces: the text must print exactly as it is,
-            // without breaking when spaces appear in the text and without
-            // consolidating spaces. If a line terminator is used, a line
-            // break will occur.
-            for ( index = 0 ; index < text.length() ; ++index ) {
-                ch = text.charAt( index );
-                if ( ch == '\n' || ch == '\r' || unescaped ) 
-                    _printer.printText( ch );
-                else
-                    printEscaped( ch );
-            }
-        } else {
-            // Not preserving spaces: print one part at a time, and
-            // use spaces between parts to break them into different
-            // lines. Spaces at beginning of line will be stripped
-            // by printing mechanism. Line terminator is treated
-            // no different than other text part.
-            for ( index = 0 ; index < text.length() ; ++index ) {
-                ch = text.charAt( index );
-                if ( ch == ' ' || ch == '\f' || ch == '\t' || ch == '\n' || ch == '\r' )
-                    _printer.printSpace();
-                else if ( unescaped )
-                    _printer.printText( ch );
-                else
-                    printEscaped( ch );
-            }
-        }
-    }
-
-
-    /**
-     * Print a document type public or system identifier URL.
-     * Encapsulates the URL in double quotes, escapes non-printing
-     * characters and print it equivalent to {@link #printText}.
-     *
-     * @param url The document type url to print
-     */
-    protected void printDoctypeURL( String url )
-    {
-        int                i;
-
-        _printer.printText( '"' );
-        for( i = 0 ; i < url.length() ; ++i ) {
-            if ( url.charAt( i ) == '"' ||  url.charAt( i ) < 0x20 || url.charAt( i ) > 0x7F ) {
-                _printer.printText( '%' );
-                _printer.printText( Integer.toHexString( url.charAt( i ) ) );
-            } else
-                _printer.printText( url.charAt( i ) );
-        }
-        _printer.printText( '"' );
-    }
-
-
-    protected void printEscaped( char ch )
-    {
-        String charRef;
-
-        // If there is a suitable entity reference for this
-        // character, print it. The list of available entity
-        // references is almost but not identical between
-        // XML and HTML.
-        charRef = getEntityRef( ch );
-        if ( charRef != null ) {
-            _printer.printText( '&' );
-            _printer.printText( charRef );
-            _printer.printText( ';' );
-        } else if ( ( ch >= ' ' && ch <= _lastPrintable && ch != 0xF7 ) ||
-                    ch == '\n' || ch == '\r' || ch == '\t' ) {
-            // If the character is not printable, print as character reference.
-            // Non printables are below ASCII space but not tab or line
-            // terminator, ASCII delete, or above a certain Unicode threshold.
-            _printer.printText( ch );
-        } else {
-            _printer.printText( "&#" );
-            _printer.printText( Integer.toString( ch ) );
-            _printer.printText( ';' );
-        }
-    }
-
-
-    /**
-     * Escapes a string so it may be printed as text content or attribute
-     * value. Non printable characters are escaped using character references.
-     * Where the format specifies a deault entity reference, that reference
-     * is used (e.g. <tt>&amp;lt;</tt>).
-     *
-     * @param source The string to escape
-     */
-    protected void printEscaped( String source )
-    {
-        for ( int i = 0 ; i < source.length() ; ++i )
-            printEscaped( source.charAt( i ) );
-    }
-
-
-    //--------------------------------//
-    // Element state handling methods //
-    //--------------------------------//
-
-
-    /**
-     * Return the state of the current element.
-     *
-     * @return Current element state
-     */
-    protected ElementState getElementState()
-    {
-        return _elementStates[ _elementStateCount ];
-    }
-
-
-    /**
-     * Enter a new element state for the specified element.
-     * Tag name and space preserving is specified, element
-     * state is initially empty.
-     *
-     * @return Current element state, or null
-     */
-    protected ElementState enterElementState( String namespaceURI, String localName,
-                                              String rawName, boolean preserveSpace )
-    {
-        ElementState state;
-
-        if ( _elementStateCount + 1 == _elementStates.length ) {
-            ElementState[] newStates;
-
-            // Need to create a larger array of states. This does not happen
-            // often, unless the document is really deep.
-            newStates = new ElementState[ _elementStates.length + 10 ];
-            for ( int i = 0 ; i < _elementStates.length ; ++i )
-                newStates[ i ] = _elementStates[ i ];
-            for ( int i = _elementStates.length ; i < newStates.length ; ++i )
-                newStates[ i ] = new ElementState();
-            _elementStates = newStates;
-        }
-
-        ++_elementStateCount;
-        state = _elementStates[ _elementStateCount ];
-        state.namespaceURI = namespaceURI;
-        state.localName = localName;
-        state.rawName = rawName;
-        state.preserveSpace = preserveSpace;
-        state.empty = true;
-        state.afterElement = false;
-        state.doCData = state.inCData = false;
-        state.unescaped = false;
-        state.prefixes = _prefixes;
-
-        _prefixes = null;
-        return state;
-    }
-
-
-    /**
-     * Leave the current element state and return to the
-     * state of the parent element. If this was the root
-     * element, return to the state of the document.
-     *
-     * @return Previous element state
-     */
-    protected ElementState leaveElementState()
-    {
-        if ( _elementStateCount > 0 ) {
-            _prefixes = _elementStates[ _elementStateCount ].prefixes;
-            -- _elementStateCount;
-            return _elementStates[ _elementStateCount ];
-        } else
-            throw new IllegalStateException( "Internal error: element state is zero" );
-    }
-
-
-    /**
-     * Returns true if in the state of the document.
-     * Returns true before entering any element and after
-     * leaving the root element.
-     *
-     * @return True if in the state of the document
-     */
-    protected boolean isDocumentState()
-    {
-        return _elementStateCount == 0;
-    }
-
-
-    /**
-     * Returns the namespace prefix for the specified URI.
-     * If the URI has been mapped to a prefix, returns the
-     * prefix, otherwise returns null.
-     *
-     * @param namespaceURI The namespace URI
-     * @return The namespace prefix if known, or null
-     */
-    protected String getPrefix( String namespaceURI )
-    {
-        String    prefix;
-
-        if ( _prefixes != null ) {
-            prefix = (String) _prefixes.get( namespaceURI );
-            if ( prefix != null )
-                return prefix;
-        }
-        if ( _elementStateCount == 0 )
-            return null;
-        else {
-            for ( int i = _elementStateCount ; i > 0 ; --i ) {
-                if ( _elementStates[ i ].prefixes != null ) {
-                    prefix = (String) _elementStates[ i ].prefixes.get( namespaceURI );
-                    if ( prefix != null )
-                        return prefix;
-                }
-            }
-        }
-        return null;
-    }
-
-
-}
diff --git a/src/org/apache/xml/serialize/DOMSerializer.java b/src/org/apache/xml/serialize/DOMSerializer.java
deleted file mode 100644
index c5e13ec..0000000
--- a/src/org/apache/xml/serialize/DOMSerializer.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xml.serialize;
-
-
-import java.io.IOException;
-import org.w3c.dom.Element;
-import org.w3c.dom.Document;
-import org.w3c.dom.DocumentFragment;
-
-
-
-/**
- * Interface for a DOM serializer implementation.
- * 
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:Scott_Boag/CAM/Lotus@lotus.com">Scott Boag</a>
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- */
-public interface DOMSerializer
-{
-
-
-    /**
-     * Serialized the DOM element. Throws an exception only if
-     * an I/O exception occured while serializing.
-     *
-     * @param elem The element to serialize
-     * @throws IOException An I/O exception occured while
-     *   serializing
-     */
-    public void serialize( Element elem )
-        throws IOException;
-
-
-    /**
-     * Serializes the DOM document. Throws an exception only if
-     * an I/O exception occured while serializing.
-     *
-     * @param doc The document to serialize
-     * @throws IOException An I/O exception occured while
-     *   serializing
-     */
-    public void serialize( Document doc )
-        throws IOException;
-
-
-    /**
-     * Serializes the DOM document fragment. Throws an exception
-     * only if an I/O exception occured while serializing.
-     *
-     * @param frag The document fragment to serialize
-     * @throws IOException An I/O exception occured while
-     *   serializing
-     */
-    public void serialize( DocumentFragment frag )
-        throws IOException;
-
-
-}
-
-
-
diff --git a/src/org/apache/xml/serialize/ElementState.java b/src/org/apache/xml/serialize/ElementState.java
deleted file mode 100644
index 4f69235..0000000
--- a/src/org/apache/xml/serialize/ElementState.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xml.serialize;
-
-
-import java.util.Hashtable;
-
-
-/**
- * Holds the state of the currently serialized element.
- *
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- * @see BaseMarkupSerializer
- */
-class ElementState
-{
-
-
-    /**
-     * The element's raw tag name (local or prefix:local).
-     */
-    String rawName;
-
-
-    /**
-     * The element's local tag name.
-     */
-    String localName;
-
-
-    /**
-     * The element's namespace URI.
-     */
-    String namespaceURI;
-
-
-    /**
-     * True if element is space preserving.
-     */
-    boolean preserveSpace;
-
-
-    /**
-     * True if element is empty. Turns false immediately
-     * after serializing the first contents of the element.
-     */
-    boolean empty;
-
-
-    /**
-     * True if the last serialized node was an element node.
-     */
-    boolean afterElement;
-
-
-    /**
-     * True if textual content of current element should be
-     * serialized as CDATA section.
-     */
-    boolean doCData;
-
-
-    /**
-     * True if textual content of current element should be
-     * serialized as raw characters (unescaped).
-     */
-    boolean unescaped;
-
-
-    /**
-     * True while inside CData and printing text as CData.
-     */
-    boolean inCData;
-
-
-    /**
-     * Association between namespace URIs (keys) and prefixes (values).
-     */
-    Hashtable prefixes;
-
-
-}
diff --git a/src/org/apache/xml/serialize/Encodings.java b/src/org/apache/xml/serialize/Encodings.java
deleted file mode 100644
index f741c5b..0000000
--- a/src/org/apache/xml/serialize/Encodings.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xml.serialize;
-
-
-import java.io.Writer;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-
-
-/**
- * Provides information about encodings. Depends on the Java runtime
- * to provides writers for the different encodings, but can be used
- * to override encoding names and provide the last printable character
- * for each encoding.
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- */
-class Encodings
-{
-
-
-    /**
-     * The last printable character for unknown encodings.
-     */
-    static final int DefaultLastPrintable = 0x7F;
-
-
-    /**
-     * Returns a writer for the specified encoding based on
-     * an output stream.
-     *
-     * @param output The output stream
-     * @param encoding The encoding
-     * @return A suitable writer
-     * @throws UnsupportedEncodingException There is no convertor
-     *  to support this encoding
-     */
-    static Writer getWriter( OutputStream output, String encoding )
-        throws UnsupportedEncodingException
-    {
-        for ( int i = 0 ; i < _encodings.length ; ++i ) {
-            if ( _encodings[ i ].name.equals( encoding ) )
-                return new OutputStreamWriter( output, _encodings[ i ].javaName );
-        }
-        return new OutputStreamWriter( output, encoding );
-    }
-
-
-    /**
-     * Returns the last printable character for the specified
-     * encoding.
-     *
-     * @param encoding The encoding
-     * @return The last printable character
-     */
-    static int getLastPrintable( String encoding )
-    {
-        for ( int i = 0 ; i < _encodings.length ; ++i ) {
-            if ( _encodings[ i ].name.equalsIgnoreCase( encoding ) )
-                return _encodings[ i ].lastPrintable;
-        }
-        return DefaultLastPrintable;
-    }
-
-
-    /**
-     * Returns the last printable character for an unspecified
-     * encoding.
-     */
-    static int getLastPrintable()
-    {
-        return DefaultLastPrintable;
-    }
-
-
-    /**
-     * Holds information about a given encoding.
-     */
-    static final class EncodingInfo
-    {
-       
-        /**
-         * The encoding name.
-         */ 
-        final String name;
-
-        /**
-         * The name used by the Java convertor.
-         */
-        final String javaName;
-
-        /**
-         * The last printable character.
-         */
-        final int    lastPrintable;
-
-        EncodingInfo( String name, String javaName, int lastPrintable )
-        {
-            this.name = name;
-            this.javaName = javaName;
-            this.lastPrintable = lastPrintable;
-        }
-
-    }
-
-
-    /**
-     * Constructs a list of all the supported encodings.
-     */
-    private static final EncodingInfo[] _encodings = new EncodingInfo[] {
-        new EncodingInfo( "ASCII", "ASCII", 0x7F ),
-        new EncodingInfo( "ISO-Latin-1", "ASCII", 0xFF ),
-        new EncodingInfo( "ISO-8859-1", "ISO8859_1", 0xFF ),
-        new EncodingInfo( "ISO-8859-2", "ISO8859_2", 0xFF ),
-        new EncodingInfo( "ISO-8859-3", "ISO8859_3", 0xFF ),
-        new EncodingInfo( "ISO-8859-4", "ISO8859_4", 0xFF ),
-        new EncodingInfo( "ISO-8859-5", "ISO8859_5", 0xFF ),
-        new EncodingInfo( "ISO-8859-6", "ISO8859_6", 0xFF ),
-        new EncodingInfo( "ISO-8859-7", "ISO8859_7", 0xFF ),
-        new EncodingInfo( "ISO-8859-8", "ISO8859_8", 0xFF ),
-        new EncodingInfo( "ISO-8859-9", "ISO8859_9", 0xFF ),
-        new EncodingInfo( "UTF-8", "UTF8", 0xFFFF ),
-        new EncodingInfo( "UNICODE", "Unicode", 0xFFFF )
-    };
-
-
-}
diff --git a/src/org/apache/xml/serialize/HTMLEntities.res b/src/org/apache/xml/serialize/HTMLEntities.res
deleted file mode 100755
index c3af002..0000000
--- a/src/org/apache/xml/serialize/HTMLEntities.res
+++ /dev/null
@@ -1,291 +0,0 @@
-# $Id$
-#
-# @version $Revision$ $Date$
-# @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
-#
-# Character entity references for markup-significant
-#
-quot 34
-amp 38
-lt 60
-gt 62
-nbsp 160
-#
-# Character entity references for ISO 8859-1 characters
-#
-iexcl 161
-cent 162
-pound 163
-curren 164
-yen 165
-brvbar 166
-sect 167
-uml 168
-copy 169
-ordf 170
-laquo 171
-not 172
-shy 173
-reg 174
-macr 175
-deg 176
-plusmn 177
-sup2 178
-sup3 179
-acute 180
-micro 181
-para 182
-middot 183
-cedil 184
-sup1 185
-ordm 186
-raquo 187
-frac14 188
-frac12 189
-frac34 190
-iquest 191
-Agrave 192
-Aacute 193
-Acirc 194
-Atilde 195
-Auml 196
-Aring 197
-AElig 198
-Ccedil 199
-Egrave 200
-Eacute 201
-Ecirc 202
-Euml 203
-Igrave 204
-Iacute 205
-Icirc 206
-Iuml 207
-ETH 208
-Ntilde 209
-Ograve 210
-Oacute 211
-Ocirc 212
-Otilde 213
-Ouml 214
-times 215
-Oslash 216
-Ugrave 217
-Uacute 218
-Ucirc 219
-Uuml 220
-Yacute 221
-THORN 222
-szlig 223
-agrave 224
-aacute 225
-acirc 226
-atilde 227
-auml 228
-aring 229
-aelig 230
-ccedil 231
-egrave 232
-eacute 233
-ecirc 234
-euml 235
-igrave 236
-iacute 237
-icirc 238
-iuml 239
-eth 240
-ntilde 241
-ograve 242
-oacute 243
-ocirc 244
-otilde 245
-ouml 246
-divide 247
-oslash 248
-ugrave 249
-uacute 250
-ucirc 251
-uuml 252
-yacute 253
-thorn 254
-yuml 255
-#
-# Character entity references for symbols, mathematical symbols, and Greek letters
-#
-# Latin Extended
-fnof 402
-#
-# Greek
-Alpha 913
-Beta 914
-Gamma 915
-Delta 916
-Epsilon 917
-Zeta 918
-Eta 919
-Theta 920
-Iota 921
-Kappa 922
-Lambda 923
-Mu 924
-Nu 925
-Xi 926
-Omicron 927
-Pi 928
-Rho 929
-Sigma 931
-Tau 932
-Upsilon 933
-Phi 934
-Chi 935
-Psi 936
-Omega 937
-alpha 945
-beta 946
-gamma 947
-delta 948
-epsilon 949
-zeta 950
-eta 951
-theta 952
-iota 953
-kappa 954
-lambda 955
-mu 956
-nu 957
-xi 958
-omicron 959
-pi 960
-rho 961
-sigmaf 962
-sigma 963
-tau 964
-upsilon 965
-phi 966
-chi 967
-psi 968
-omega 969
-thetasym 977
-upsih 978
-piv 982
-#
-# General Punctuation
-bull 8226
-hellip 8230
-prime 8242
-Prime 8243
-oline 8254
-frasl 8260
-#
-# Letterlike Symbols
-weierp 8472
-image 8465
-real 8476
-trade 8482
-alefsym 8501
-#
-# Arrows
-larr 8592
-uarr 8593
-rarr 8594
-darr 8595
-harr 8596
-crarr 8629
-lArr 8656
-uArr 8657
-rArr 8658
-dArr 8659
-hArr 8660
-#
-# Mathematical Operators
-forall 8704
-part 8706
-exist 8707
-empty 8709
-nabla 8711
-isin 8712
-notin 8713
-ni 8715
-prod 8719
-sum 8721
-minus 8722
-lowast 8727
-radic 8730
-prop 8733
-infin 8734
-ang 8736
-and 8743
-or 8744
-cap 8745
-cup 8746
-int 8747
-there4 8756
-sim 8764
-cong 8773
-asymp 8776
-ne 8800
-equiv 8801
-le 8804
-ge 8805
-sub 8834
-sup 8835
-nsub 8836
-sube 8838
-supe 8839
-oplus 8853
-otimes 8855
-perp 8869
-sdot 8901
-#
-# Miscellaneous Technical
-lceil 8968
-rceil 8969
-lfloor 8970
-rfloor 8971
-lang 9001
-rang 9002
-#
-# Geometric Shapes
-loz 9674
-#
-# Miscellaneous Symbols
-spades 9824
-clubs 9827
-hearts 9829
-diams 9830
-#
-# Character entity references for internationalization characters
-#
-# Latin Extended-A
-OElig 338
-oelig 339
-#-- Commented out. NN 4.7 does not seem to support these --
-#Scaron 352
-#scaron 353
-Yuml 376
-#
-# Spacing Modifier Letters
-circ 710
-tilde 732
-#
-# General Punctuation
-ensp 8194
-emsp 8195
-thinsp 8201
-zwnj 8204
-zwj 8205
-lrm 8206
-rlm 8207
-ndash 8211
-mdash 8212
-lsquo 8216
-rsquo 8217
-sbquo 8218
-ldquo 8220
-rdquo 8221
-bdquo 8222
-dagger 8224
-Dagger 8225
-permil 8240
-lsaquo 8249
-rsaquo 8250
-euro 8364
diff --git a/src/org/apache/xml/serialize/HTMLSerializer.java b/src/org/apache/xml/serialize/HTMLSerializer.java
deleted file mode 100755
index 3254177..0000000
--- a/src/org/apache/xml/serialize/HTMLSerializer.java
+++ /dev/null
@@ -1,838 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-// Aug 21, 2000:
-//  Fixed bug in startDocument not calling prepare.
-//  Reported by Mikael Staldal <d96-mst-ingen-reklam@d.kth.se>
-// Aug 21, 2000:
-//  Added ability to omit DOCTYPE declaration.
-
-
-package org.apache.xml.serialize;
-
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.io.OutputStream;
-import java.io.Writer;
-import java.util.Enumeration;
-
-import org.w3c.dom.Element;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Node;
-import org.w3c.dom.NamedNodeMap;
-import org.xml.sax.DocumentHandler;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.AttributeList;
-import org.xml.sax.Attributes;
-
-
-/**
- * Implements an HTML/XHTML serializer supporting both DOM and SAX
- * pretty serializing. HTML/XHTML mode is determined in the
- * constructor.  For usage instructions see {@link Serializer}.
- * <p>
- * If an output stream is used, the encoding is taken from the
- * output format (defaults to <tt>UTF-8</tt>). If a writer is
- * used, make sure the writer uses the same encoding (if applies)
- * as specified in the output format.
- * <p>
- * The serializer supports both DOM and SAX. DOM serializing is done
- * by calling {@link #serialize} and SAX serializing is done by firing
- * SAX events and using the serializer as a document handler.
- * <p>
- * If an I/O exception occurs while serializing, the serializer
- * will not throw an exception directly, but only throw it
- * at the end of serializing (either DOM or SAX's {@link
- * org.xml.sax.DocumentHandler#endDocument}.
- * <p>
- * For elements that are not specified as whitespace preserving,
- * the serializer will potentially break long text lines at space
- * boundaries, indent lines, and serialize elements on separate
- * lines. Line terminators will be regarded as spaces, and
- * spaces at beginning of line will be stripped.
- * <p>
- * XHTML is slightly different than HTML:
- * <ul>
- * <li>Element/attribute names are lower case and case matters
- * <li>Attributes must specify value, even if empty string
- * <li>Empty elements must have '/' in empty tag
- * <li>Contents of SCRIPT and STYLE elements serialized as CDATA
- * </ul>
- *
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- * @see Serializer
- */
-public class HTMLSerializer
-    extends BaseMarkupSerializer
-{
-
-
-    /**
-     * True if serializing in XHTML format.
-     */
-    private static boolean _xhtml;
-
-
-    public static String XHTMLNamespace = "";
-
-
-
-
-    /**
-     * Constructs a new HTML/XHTML serializer depending on the value of
-     * <tt>xhtml</tt>. The serializer cannot be used without calling
-     * {@link #init} first.
-     *
-     * @param xhtml True if XHTML serializing
-     */
-    protected HTMLSerializer( boolean xhtml, OutputFormat format )
-    {
-        super( format );
-        _xhtml = xhtml;
-    }
-
-
-    /**
-     * Constructs a new serializer. The serializer cannot be used without
-     * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
-     * first.
-     */
-    public HTMLSerializer()
-    {
-        this( false, new OutputFormat( Method.HTML, null, false ) );
-    }
-
-
-    /**
-     * Constructs a new serializer. The serializer cannot be used without
-     * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
-     * first.
-     */
-    public HTMLSerializer( OutputFormat format )
-    {
-        this( false, format != null ? format : new OutputFormat( Method.HTML, null, false ) );
-    }
-
-
-
-    /**
-     * Constructs a new serializer that writes to the specified writer
-     * using the specified output format. If <tt>format</tt> is null,
-     * will use a default output format.
-     *
-     * @param writer The writer to use
-     * @param format The output format to use, null for the default
-     */
-    public HTMLSerializer( Writer writer, OutputFormat format )
-    {
-        this( false, format != null ? format : new OutputFormat( Method.HTML, null, false ) );
-        setOutputCharStream( writer );
-    }
-
-
-    /**
-     * Constructs a new serializer that writes to the specified output
-     * stream using the specified output format. If <tt>format</tt>
-     * is null, will use a default output format.
-     *
-     * @param output The output stream to use
-     * @param format The output format to use, null for the default
-     */
-    public HTMLSerializer( OutputStream output, OutputFormat format )
-    {
-        this( false, format != null ? format : new OutputFormat( Method.HTML, null, false ) );
-        setOutputByteStream( output );
-    }
-    
-    
-    public void setOutputFormat( OutputFormat format )
-    {
-        super.setOutputFormat( format != null ? format : new OutputFormat( Method.HTML, null, false ) );
-    }
-
-
-    //-----------------------------------------//
-    // SAX content handler serializing methods //
-    //-----------------------------------------//
-
-
-    public void startElement( String namespaceURI, String localName,
-                              String rawName, Attributes attrs )
-    {
-        int          i;
-        boolean      preserveSpace;
-        ElementState state;
-        String       name;
-        String       value;
-        String       htmlName;
-        boolean      addNSAttr = false;
-        
-        if ( _printer == null )
-            throw new IllegalStateException( "SER002 No writer supplied for serializer" );
-        
-        state = getElementState();
-        if ( isDocumentState() ) {
-            // If this is the root element handle it differently.
-            // If the first root element in the document, serialize
-            // the document's DOCTYPE. Space preserving defaults
-            // to that of the output format.
-            if ( ! _started )
-                startDocument( localName == null ? rawName : localName );
-        } else {
-            // For any other element, if first in parent, then
-            // close parent's opening tag and use the parnet's
-            // space preserving.
-            if ( state.empty )
-                _printer.printText( '>' );
-            // Indent this element on a new line if the first
-            // content of the parent element or immediately
-            // following an element.
-            if ( _indenting && ! state.preserveSpace &&
-                 ( state.empty || state.afterElement ) )
-                _printer.breakLine();
-        }
-        preserveSpace = state.preserveSpace;
-
-        // Do not change the current element state yet.
-        // This only happens in endElement().
-        
-        if ( rawName == null ) {
-            rawName = localName;
-            if ( namespaceURI != null ) {
-                String prefix;
-                prefix = getPrefix( namespaceURI );
-                if ( prefix.length() > 0 )
-                    rawName = prefix + ":" + localName;
-            }
-            addNSAttr = true;
-        }
-        if ( namespaceURI == null )
-            htmlName = rawName;
-        else {
-            if ( namespaceURI.equals( XHTMLNamespace ) )
-                htmlName = localName;
-            else
-                htmlName = null;
-        }
-        
-        // XHTML: element names are lower case, DOM will be different
-        _printer.printText( '<' );
-        if ( _xhtml )
-            _printer.printText( rawName.toLowerCase() );
-        else
-            _printer.printText( rawName );
-        _printer.indent();
-        
-        // For each attribute serialize it's name and value as one part,
-        // separated with a space so the element can be broken on
-        // multiple lines.
-        if ( attrs != null ) {
-            for ( i = 0 ; i < attrs.getLength() ; ++i ) {
-                _printer.printSpace();
-                name = attrs.getQName( i ).toLowerCase();;
-                value = attrs.getValue( i );
-                if ( _xhtml || namespaceURI != null ) {
-                    // XHTML: print empty string for null values.
-                    if ( value == null ) {
-                        _printer.printText( name );
-                        _printer.printText( "=\"\"" );
-                    } else {
-                        _printer.printText( name );
-                        _printer.printText( "=\"" );
-                        printEscaped( value );
-                        _printer.printText( '"' );
-                    }
-                } else {
-                    // HTML: Empty values print as attribute name, no value.
-                    // HTML: URI attributes will print unescaped
-                    if ( value == null || value.length() == 0 )
-                        _printer.printText( name );
-                    else if ( HTMLdtd.isURI( rawName, name ) ) {
-                        _printer.printText( name );
-                        _printer.printText( "=\"" ); 
-                        _printer.printText( escapeURI( value ) );
-                        _printer.printText( '"' );
-                    } else if ( HTMLdtd.isBoolean( rawName, name ) )
-                        _printer.printText( name );
-                    else {
-                        _printer.printText( name );
-                        _printer.printText( "=\"" );
-                        printEscaped( value );
-                        _printer.printText( '"' );
-                    }
-                }
-            }
-        }
-        if ( htmlName != null && HTMLdtd.isPreserveSpace( htmlName ) )
-            preserveSpace = true;
-        
-        if ( addNSAttr ) {
-            Enumeration enum;
-            
-            enum = _prefixes.keys();
-            while ( enum.hasMoreElements() ) {
-                _printer.printSpace();
-                value = (String) enum.nextElement();
-                name = (String) _prefixes.get( value );
-                if ( name.length() == 0 ) {
-                    _printer.printText( "xmlns=\"" );
-                    printEscaped( value );
-                    _printer.printText( '"' );
-                } else {
-                    _printer.printText( "xmlns:" );
-                    _printer.printText( name );
-                    _printer.printText( "=\"" );
-                    printEscaped( value );
-                    _printer.printText( '"' );
-                }
-            }
-        }
-        
-        // Now it's time to enter a new element state
-        // with the tag name and space preserving.
-        // We still do not change the curent element state.
-        state = enterElementState( namespaceURI, localName, rawName, preserveSpace );
-        
-        // Prevents line breaks inside A/TD
-        
-        if ( htmlName != null && ( htmlName.equalsIgnoreCase( "A" ) ||
-                                   htmlName.equalsIgnoreCase( "TD" ) ) ) {
-            state.empty = false;
-            _printer.printText( '>' );
-        }
-        
-        // Handle SCRIPT and STYLE specifically by changing the
-        // state of the current element to CDATA (XHTML) or
-        // unescaped (HTML).
-        if ( htmlName != null && ( rawName.equalsIgnoreCase( "SCRIPT" ) ||
-                                   rawName.equalsIgnoreCase( "STYLE" ) ) ) {
-            if ( _xhtml ) {
-                // XHTML: Print contents as CDATA section
-                state.doCData = true;
-            } else {
-                // HTML: Print contents unescaped
-                state.unescaped = true;
-            }
-        }
-    }
-    
-    
-    public void endElement( String namespaceURI, String localName,
-                            String rawName )
-    {
-        ElementState state;
-        String       htmlName;
-        
-        // Works much like content() with additions for closing
-        // an element. Note the different checks for the closed
-        // element's state and the parent element's state.
-        _printer.unindent();
-        state = getElementState();
-        
-        if ( state.namespaceURI == null )
-            htmlName = state.rawName;
-        else {
-            if ( state.namespaceURI.equals( XHTMLNamespace ) )
-                htmlName = state.localName;
-            else
-                htmlName = null;
-        }
-        
-        if ( _xhtml) {
-            if ( state.empty ) {
-                _printer.printText( " />" );
-            } else {
-                // Must leave CData section first
-                if ( state.inCData )
-                    _printer.printText( "]]>" );
-                // XHTML: element names are lower case, DOM will be different
-                _printer.printText( "</" );
-                _printer.printText( state.rawName.toLowerCase() );
-                _printer.printText( '>' );
-            }
-        } else {
-            if ( state.empty )
-                _printer.printText( '>' );
-            // This element is not empty and that last content was
-            // another element, so print a line break before that
-            // last element and this element's closing tag.
-            // [keith] Provided this is not an anchor.
-            // HTML: some elements do not print closing tag (e.g. LI)
-            if ( htmlName == null || ! HTMLdtd.isOnlyOpening( htmlName ) ) {
-                if ( _indenting && ! state.preserveSpace && state.afterElement )
-                    _printer.breakLine();
-                // Must leave CData section first (Illegal in HTML, but still)
-                if ( state.inCData )
-                    _printer.printText( "]]>" );
-                _printer.printText( "</" );
-                _printer.printText( state.rawName );
-                _printer.printText( '>' );
-            }
-        }
-        // Leave the element state and update that of the parent
-        // (if we're not root) to not empty and after element.
-        state = leaveElementState();
-        // Temporary hack to prevent line breaks inside A/TD
-        if ( htmlName == null || ( ! htmlName.equalsIgnoreCase( "A" ) &&
-                                   ! htmlName.equalsIgnoreCase( "TD" ) ) )
-            
-            state.afterElement = true;
-        state.empty = false;
-        if ( isDocumentState() )
-            _printer.flush();
-    }
-    
-    
-    //------------------------------------------//
-    // SAX document handler serializing methods //
-    //------------------------------------------//
-
-
-    public void characters( char[] chars, int start, int length )
-    {
-        ElementState state;
-        
-        // HTML: no CDATA section
-        state = content();
-        state.doCData = false;
-        super.characters( chars, start, length );
-    }
-    
-    
-    public void startElement( String tagName, AttributeList attrs )
-    {
-        int          i;
-        boolean      preserveSpace;
-        ElementState state;
-        String       name;
-        String       value;
-        
-        if ( _printer == null )
-            throw new IllegalStateException( "SER002 No writer supplied for serializer" );
-        
-        state = getElementState();
-        if ( isDocumentState() ) {
-            // If this is the root element handle it differently.
-            // If the first root element in the document, serialize
-            // the document's DOCTYPE. Space preserving defaults
-            // to that of the output format.
-            if ( ! _started )
-                startDocument( tagName );
-        } else {
-            // For any other element, if first in parent, then
-            // close parent's opening tag and use the parnet's
-            // space preserving.
-            if ( state.empty )
-                _printer.printText( '>' );
-            // Indent this element on a new line if the first
-            // content of the parent element or immediately
-            // following an element.
-            if ( _indenting && ! state.preserveSpace &&
-                 ( state.empty || state.afterElement ) )
-                _printer.breakLine();
-        }
-        preserveSpace = state.preserveSpace;
-
-        // Do not change the current element state yet.
-        // This only happens in endElement().
-        
-        // XHTML: element names are lower case, DOM will be different
-        _printer.printText( '<' );
-        if ( _xhtml )
-            _printer.printText( tagName.toLowerCase() );
-        else
-            _printer.printText( tagName );
-        _printer.indent();
-        
-        // For each attribute serialize it's name and value as one part,
-        // separated with a space so the element can be broken on
-        // multiple lines.
-        if ( attrs != null ) {
-            for ( i = 0 ; i < attrs.getLength() ; ++i ) {
-                _printer.printSpace();
-                name = attrs.getName( i ).toLowerCase();;
-                value = attrs.getValue( i );
-                if ( _xhtml ) {
-                    // XHTML: print empty string for null values.
-                    if ( value == null ) {
-                        _printer.printText( name );
-                        _printer.printText( "=\"\"" );
-                    } else {
-                        _printer.printText( name );
-                        _printer.printText( "=\"" ); 
-                        printEscaped( value );
-                        _printer.printText( '"' );
-                    }
-                } else {
-                    // HTML: Empty values print as attribute name, no value.
-                    // HTML: URI attributes will print unescaped
-                    if ( value == null || value.length() == 0 )
-                        _printer.printText( name );
-                    else if ( HTMLdtd.isURI( tagName, name ) ) {
-                        _printer.printText( name );
-                        _printer.printText( "=\"" ); 
-                        _printer.printText( escapeURI( value ) );
-                        _printer.printText( '"' );
-                    } else if ( HTMLdtd.isBoolean( tagName, name ) )
-                        _printer.printText( name );
-                    else {
-                        _printer.printText( name );
-                        _printer.printText( "=\"" ); 
-                        printEscaped( value );
-                        _printer.printText( '"' );
-                    }
-                }
-            }
-        }
-        if ( HTMLdtd.isPreserveSpace( tagName ) )
-            preserveSpace = true;
-        
-        // Now it's time to enter a new element state
-        // with the tag name and space preserving.
-        // We still do not change the curent element state.
-        state = enterElementState( null, null, tagName, preserveSpace );
-        
-        // Prevents line breaks inside A/TD
-        if ( tagName.equalsIgnoreCase( "A" ) || tagName.equalsIgnoreCase( "TD" ) ) {
-            state.empty = false;
-            _printer.printText( '>' );
-        }
-        
-        // Handle SCRIPT and STYLE specifically by changing the
-        // state of the current element to CDATA (XHTML) or
-        // unescaped (HTML).
-        if ( tagName.equalsIgnoreCase( "SCRIPT" ) ||
-             tagName.equalsIgnoreCase( "STYLE" ) ) {
-            if ( _xhtml ) {
-                // XHTML: Print contents as CDATA section
-                state.doCData = true;
-            } else {
-                // HTML: Print contents unescaped
-                state.unescaped = true;
-            }
-        }
-    }
-    
-    
-    public void endElement( String tagName )
-    {
-        endElement( null, null, tagName );
-    }
-
-
-    //------------------------------------------//
-    // Generic node serializing methods methods //
-    //------------------------------------------//
-
-
-    /**
-     * Called to serialize the document's DOCTYPE by the root element.
-     * The document type declaration must name the root element,
-     * but the root element is only known when that element is serialized,
-     * and not at the start of the document.
-     * <p>
-     * This method will check if it has not been called before ({@link #_started}),
-     * will serialize the document type declaration, and will serialize all
-     * pre-root comments and PIs that were accumulated in the document
-     * (see {@link #serializePreRoot}). Pre-root will be serialized even if
-     * this is not the first root element of the document.
-     */
-    protected void startDocument( String rootTagName )
-    {
-        StringBuffer buffer;
-        
-        // Not supported in HTML/XHTML, but we still have to switch
-        // out of DTD mode.
-        _printer.leaveDTD();
-        if ( ! _started ) {
-            // If the public and system identifiers were not specified
-            // in the output format, use the appropriate ones for HTML
-            // or XHTML.
-            if ( _docTypePublicId == null && _docTypeSystemId == null ) {
-                if ( _xhtml ) {
-                    _docTypePublicId = OutputFormat.DTD.XHTMLPublicId;
-                    _docTypeSystemId = OutputFormat.DTD.XHTMLSystemId;
-                } else {
-                    _docTypePublicId = OutputFormat.DTD.HTMLPublicId;
-                    _docTypeSystemId = OutputFormat.DTD.HTMLSystemId;
-                }
-            }
-
-            if ( ! _format.getOmitDocumentType() ) {
-                // XHTML: If public idnentifier and system identifier
-                //  specified, print them, else print just system identifier
-                // HTML: If public identifier specified, print it with
-                //  system identifier, if specified.
-                if ( _docTypePublicId != null && ( ! _xhtml || _docTypeSystemId != null )  ) {
-                    _printer.printText( "<!DOCTYPE HTML PUBLIC " );
-                    printDoctypeURL( _docTypePublicId );
-                    if ( _docTypeSystemId != null ) {
-                        if ( _indenting ) {
-                            _printer.breakLine();
-                            _printer.printText( "                      " );
-                        } else
-                        _printer.printText( ' ' );
-                        printDoctypeURL( _docTypeSystemId );
-                    }
-                    _printer.printText( '>' );
-                    _printer.breakLine();
-                } else if ( _docTypeSystemId != null ) {
-                    _printer.printText( "<!DOCTYPE HTML SYSTEM " );
-                    printDoctypeURL( _docTypeSystemId );
-                    _printer.printText( '>' );
-                    _printer.breakLine();
-                }
-            }
-        }
-        
-        _started = true;
-        // Always serialize these, even if not te first root element.
-        serializePreRoot();
-    }
-
-
-    /**
-     * Called to serialize a DOM element. Equivalent to calling {@link
-     * #startElement}, {@link #endElement} and serializing everything
-     * inbetween, but better optimized.
-     */
-    protected void serializeElement( Element elem )
-    {
-        Attr         attr;
-        NamedNodeMap attrMap;
-        int          i;
-        Node         child;
-        ElementState state;
-        boolean      preserveSpace;
-        String       name;
-        String       value;
-        String       tagName;
-        
-        tagName = elem.getTagName();
-        state = getElementState();
-        if ( isDocumentState() ) {
-            // If this is the root element handle it differently.
-            // If the first root element in the document, serialize
-            // the document's DOCTYPE. Space preserving defaults
-            // to that of the output format.
-            if ( ! _started )
-                startDocument( tagName );
-        } else {
-            // For any other element, if first in parent, then
-            // close parent's opening tag and use the parnet's
-            // space preserving.
-            if ( state.empty )
-                _printer.printText( '>' );
-            // Indent this element on a new line if the first
-            // content of the parent element or immediately
-            // following an element.
-            if ( _indenting && ! state.preserveSpace &&
-                 ( state.empty || state.afterElement ) )
-                _printer.breakLine();
-        }
-        preserveSpace = state.preserveSpace;
-
-        // Do not change the current element state yet.
-        // This only happens in endElement().
-        
-        // XHTML: element names are lower case, DOM will be different
-        _printer.printText( '<' );
-        if ( _xhtml )
-            _printer.printText( tagName.toLowerCase() );
-        else
-            _printer.printText( tagName );
-        _printer.indent();
-        
-        // Lookup the element's attribute, but only print specified
-        // attributes. (Unspecified attributes are derived from the DTD.
-        // For each attribute print it's name and value as one part,
-        // separated with a space so the element can be broken on
-        // multiple lines.
-        attrMap = elem.getAttributes();
-        if ( attrMap != null ) {
-            for ( i = 0 ; i < attrMap.getLength() ; ++i ) {
-                attr = (Attr) attrMap.item( i );
-                name = attr.getName().toLowerCase();
-                value = attr.getValue();
-                if ( attr.getSpecified() ) {
-                    _printer.printSpace();
-                    if ( _xhtml ) {
-                        // XHTML: print empty string for null values.
-                        if ( value == null ) {
-                            _printer.printText( name );
-                            _printer.printText( "=\"\"" );
-                        } else {
-                            _printer.printText( name );
-                            _printer.printText( "=\"" );
-                            printEscaped( value );
-                            _printer.printText( '"' );
-                        }
-                    } else {
-                        // HTML: Empty values print as attribute name, no value.
-                        // HTML: URI attributes will print unescaped
-                        if ( value == null || value.length() == 0 )
-                            _printer.printText( name );
-                        else if ( HTMLdtd.isURI( tagName, name ) ) {
-                            _printer.printText( name );
-                            _printer.printText( "=\"" );
-                            _printer.printText( escapeURI( value ) );
-                            _printer.printText( '"' );
-                        } else if ( HTMLdtd.isBoolean( tagName, name ) )
-                            _printer.printText( name );
-                        else {
-                            _printer.printText( name );
-                            _printer.printText( "=\"" );
-                            printEscaped( value );
-                            _printer.printText( '"' );
-                        }
-                    }
-                }
-            }
-        }
-        if ( HTMLdtd.isPreserveSpace( tagName ) )
-            preserveSpace = true;
-        
-        // If element has children, or if element is not an empty tag,
-        // serialize an opening tag.
-        if ( elem.hasChildNodes() || ! HTMLdtd.isEmptyTag( tagName ) ) {
-            // Enter an element state, and serialize the children
-            // one by one. Finally, end the element.
-            state = enterElementState( null, null, tagName, preserveSpace );
-            
-            // Prevents line breaks inside A/TD
-            if ( tagName.equalsIgnoreCase( "A" ) || tagName.equalsIgnoreCase( "TD" ) ) {
-                state.empty = false;
-                _printer.printText( '>' );
-            }
-            
-            // Handle SCRIPT and STYLE specifically by changing the
-            // state of the current element to CDATA (XHTML) or
-            // unescaped (HTML).
-            if ( tagName.equalsIgnoreCase( "SCRIPT" ) ||
-                 tagName.equalsIgnoreCase( "STYLE" ) ) {
-                if ( _xhtml ) {
-                    // XHTML: Print contents as CDATA section
-                    state.doCData = true;
-                } else {
-                    // HTML: Print contents unescaped
-                    state.unescaped = true;
-                }
-            }
-            child = elem.getFirstChild();
-            while ( child != null ) {
-                serializeNode( child );
-                child = child.getNextSibling();
-            }
-            endElement( null, null, tagName );
-        } else {
-            _printer.unindent();
-            // XHTML: Close empty tag with ' />' so it's XML and HTML compatible.
-            // HTML: Empty tags are defined as such in DTD no in document.
-            if ( _xhtml )
-                _printer.printText( " />" );
-            else
-                _printer.printText( '>' );
-            // After element but parent element is no longer empty.
-            state.afterElement = true;
-            state.empty = false;
-            if ( isDocumentState() )
-                _printer.flush();
-        }
-    }
-
-
-
-    protected void characters( String text )
-    {
-        ElementState state;
-        
-        // HTML: no CDATA section
-        state = content();
-        state.doCData = false;
-        super.characters( text );
-    }
-    
-    
-    protected String getEntityRef( char ch )
-    {
-        return HTMLdtd.fromChar( ch );
-    }
-
-
-    protected String escapeURI( String uri )
-    {
-        int index;
-        
-        // XXX  Apparently Netscape doesn't like if we escape the URI
-        //      using %nn, so we leave it as is, just remove any quotes.
-        index = uri.indexOf( "\"" );
-        if ( index >= 0 )
-            return uri.substring( 0, index );
-        else
-            return uri;
-    }
-
-
-}
-
-
-
-
diff --git a/src/org/apache/xml/serialize/HTMLdtd.java b/src/org/apache/xml/serialize/HTMLdtd.java
deleted file mode 100755
index aee347b..0000000
--- a/src/org/apache/xml/serialize/HTMLdtd.java
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-// Aug 21, 2000:
-//   Fixed bug in isElement and made HTMLdtd public.
-//   Contributed by Eric SCHAEFFER" <eschaeffer@posterconseil.com>
-
-
-package org.apache.xml.serialize;
-
-
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.BufferedReader;
-import java.util.Hashtable;
-
-
-/**
- * Utility class for accessing information specific to HTML documents.
- * The HTML DTD is expressed as three utility function groups. Two methods
- * allow for checking whether an element requires an open tag on printing
- * ({@link #isEmptyTag}) or on parsing ({@link #isOptionalClosing}).
- * <P>
- * Two other methods translate character references from name to value and
- * from value to name. A small entities resource is loaded into memory the
- * first time any of these methods is called for fast and efficient access.
- *
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- */
-public final class HTMLdtd
-{
-
-
-    /**
-     * Table of reverse character reference mapping. Character codes are held
-     * as single-character strings, mapped to their reference name.
-     */
-    private static Hashtable        _byChar;
-
-
-    /**
-     * Table of entity name to value mapping. Entities are held as strings,
-     * character references as <TT>Character</TT> objects.
-     */
-    private static Hashtable        _byName;
-
-
-    private static Hashtable        _boolAttrs;
-
-
-    /**
-     * Holds element definitions.
-     */
-    private static Hashtable        _elemDefs;
-
-
-    /**
-     * Locates the HTML entities file that is loaded upon initialization.
-     * This file is a resource loaded with the default class loader.
-     */
-    private static final String     ENTITIES_RESOURCE = "HTMLEntities.res";
-
-
-    /**
-     * Only opening tag should be printed.
-     */
-    private static final int ONLY_OPENING = 0x0001;
-
-    /**
-     * Element contains element content only.
-     */
-    private static final int ELEM_CONTENT = 0x0002;
-
-
-    /**
-     * Element preserve spaces.
-     */
-    private static final int PRESERVE     = 0x0004;
-
-
-    /**
-     * Optional closing tag.
-     */
-    private static final int OPT_CLOSING  = 0x0008;
-
-
-    /**
-     * Element is empty (also means only opening tag)
-     */
-    private static final int EMPTY        = 0x0010 | ONLY_OPENING;
-
-
-    /**
-     * Allowed to appear in head.
-     */
-    private static final int ALLOWED_HEAD = 0x0020;
-
-
-    /**
-     * When opened, closes P.
-     */
-    private static final int CLOSE_P      = 0x0040;
-
-
-    /**
-     * When opened, closes DD or DT.
-     */
-    private static final int CLOSE_DD_DT  = 0x0080;
-
-
-    /**
-     * When opened, closes itself.
-     */
-    private static final int CLOSE_SELF   = 0x0100;
-
-
-    /**
-     * When opened, closes another table section.
-     */
-    private static final int CLOSE_TABLE  = 0x0200;
-
-
-    /**
-     * When opened, closes TH or TD.
-     */
-    private static final int CLOSE_TH_TD  = 0x04000;
-
-
-    /**
-     * Returns true if element is declared to be empty. HTML elements are
-     * defines as empty in the DTD, not by the document syntax.
-     * 
-     * @param tagName The element tag name (upper case)
-     * @return True if element is empty
-     */
-    public static boolean isEmptyTag( String tagName )
-    {
-        return isElement( tagName, EMPTY );
-    }
-
-
-    /**
-     * Returns true if element is declared to have element content.
-     * Whitespaces appearing inside element content will be ignored,
-     * other text will simply report an error.
-     * 
-     * @param tagName The element tag name (upper case)
-     * @return True if element content
-     */
-    public static boolean isElementContent( String tagName )
-    {
-        return isElement( tagName, ELEM_CONTENT );
-    }
-
-    
-    /**
-     * Returns true if element's textual contents preserves spaces.
-     * This only applies to PRE and TEXTAREA, all other HTML elements
-     * do not preserve space.
-     * 
-     * @param tagName The element tag name (upper case)
-     * @return True if element's text content preserves spaces
-     */
-    public static boolean isPreserveSpace( String tagName )
-    {
-        return isElement( tagName, PRESERVE );
-    }
-
-
-    /**
-     * Returns true if element's closing tag is optional and need not
-     * exist. An error will not be reported for such elements if they
-     * are not closed. For example, <tt>LI</tt> is most often not closed.
-     *
-     * @param tagName The element tag name (upper case)
-     * @return True if closing tag implied
-     */
-    public static boolean isOptionalClosing( String tagName )
-    {
-        return isElement( tagName, OPT_CLOSING );
-    }
-
-
-    /**
-     * Returns true if element's closing tag is generally not printed.
-     * For example, <tt>LI</tt> should not print the closing tag.
-     *
-     * @param tagName The element tag name (upper case)
-     * @return True if only opening tag should be printed
-     */
-    public static boolean isOnlyOpening( String tagName )
-    {
-        return isElement( tagName, ONLY_OPENING );
-    }
-
-
-    /**
-     * Returns true if the opening of one element (<tt>tagName</tt>) implies
-     * the closing of another open element (<tt>openTag</tt>). For example,
-     * every opening <tt>LI</tt> will close the previously open <tt>LI</tt>,
-     * and every opening <tt>BODY</tt> will close the previously open <tt>HEAD</tt>.
-     *
-     * @param tagName The newly opened element
-     * @param openTag The already opened element
-     * @return True if closing tag closes opening tag
-     */    
-    public static boolean isClosing( String tagName, String openTag )
-    {
-        // Several elements are defined as closing the HEAD
-        if ( openTag.equalsIgnoreCase( "HEAD" ) )
-            return ! isElement( tagName, ALLOWED_HEAD );
-        // P closes iteself
-        if ( openTag.equalsIgnoreCase( "P" ) )
-            return isElement( tagName, CLOSE_P );
-        // DT closes DD, DD closes DT
-        if ( openTag.equalsIgnoreCase( "DT" ) || openTag.equalsIgnoreCase( "DD" ) )
-            return isElement( tagName, CLOSE_DD_DT );
-        // LI and OPTION close themselves
-        if ( openTag.equalsIgnoreCase( "LI" ) || openTag.equalsIgnoreCase( "OPTION" ) )
-            return isElement( tagName, CLOSE_SELF );
-        // Each of these table sections closes all the others
-        if ( openTag.equalsIgnoreCase( "THEAD" ) || openTag.equalsIgnoreCase( "TFOOT" ) ||
-             openTag.equalsIgnoreCase( "TBODY" ) || openTag.equalsIgnoreCase( "TR" ) || 
-             openTag.equalsIgnoreCase( "COLGROUP" ) )
-            return isElement( tagName, CLOSE_TABLE );
-        // TD closes TH and TH closes TD
-        if ( openTag.equalsIgnoreCase( "TH" ) || openTag.equalsIgnoreCase( "TD" ) )
-            return isElement( tagName, CLOSE_TH_TD );
-        return false;
-    }
-    
-    
-    /**
-     * Returns true if the specified attribute it a URI and should be
-     * escaped appropriately. In HTML URIs are escaped differently
-     * than normal attributes.
-     *
-     * @param tagName The element's tag name
-     * @param attrName The attribute's name
-     */
-    public static boolean isURI( String tagName, String attrName )
-    {
-        // Stupid checks.
-        return ( attrName.equalsIgnoreCase( "href" ) || attrName.equalsIgnoreCase( "src" ) );
-    }
-
-        
-    /**
-     * Returns true if the specified attribute is a boolean and should be
-     * printed without the value. This applies to attributes that are true
-     * if they exist, such as selected (OPTION/INPUT). 
-     *
-     * @param tagName The element's tag name
-     * @param attrName The attribute's name
-     */
-    public static boolean isBoolean( String tagName, String attrName )
-    {
-        String[] attrNames;
-        
-        attrNames = (String[]) _boolAttrs.get( tagName.toUpperCase() );
-        if ( attrNames == null )
-            return false;
-        for ( int i = 0 ; i < attrNames.length ; ++i )
-            if ( attrNames[ i ].equalsIgnoreCase( attrName ) )
-                return true;
-        return false;
-    }
-
-
-    /**
-     * Returns the value of an HTML character reference by its name. If the
-     * reference is not found or was not defined as a character reference,
-     * returns EOF (-1).
-     *
-     * @param name Name of character reference
-     * @return Character code or EOF (-1)
-     */
-    public static int charFromName( String name )
-    {
-        Object    value;
-        
-        initialize();
-        value = _byName.get( name );
-        if ( value != null && value instanceof Character )
-            return ( (Character) value ).charValue();
-        else
-            return -1;
-    }
-    
-    
-    /**
-     * Returns the name of an HTML character reference based on its character
-     * value. Only valid for entities defined from character references. If no
-     * such character value was defined, return null.
-     *
-     * @param value Character value of entity
-     * @return Entity's name or null
-     */
-    public static String fromChar( char value )
-    {
-        String    name;
-        
-        initialize();
-        name = (String) _byChar.get( String.valueOf( value ) );
-        if ( name == null )
-            return null;
-        else
-            return name;
-    }
-    
-
-    /**
-     * Initialize upon first access. Will load all the HTML character references
-     * into a list that is accessible by name or character value and is optimized
-     * for character substitution. This method may be called any number of times
-     * but will execute only once.
-     */
-    private static void initialize()
-    {
-        InputStream     is = null;
-        BufferedReader  reader = null;
-        int             index;
-        String          name;
-        String          value;
-        int             code;
-        String          line;
-        
-        // Make sure not to initialize twice.
-        if ( _byName != null )
-            return;
-        try {
-            _byName = new Hashtable();
-            _byChar = new Hashtable();
-            is = HTMLdtd.class.getResourceAsStream( ENTITIES_RESOURCE );
-            if ( is == null )
-                throw new RuntimeException( "SER003 The resource [" + ENTITIES_RESOURCE + "] could not be found.\n" + ENTITIES_RESOURCE);
-            reader = new BufferedReader( new InputStreamReader( is ) );
-            line = reader.readLine();
-            while ( line != null ) {
-                if ( line.length() == 0 || line.charAt( 0 ) == '#' ) {
-                    line = reader.readLine();
-                    continue;
-                }
-                index = line.indexOf( ' ' );
-                if ( index > 1 ) {
-                    name = line.substring( 0, index );
-                    ++index;
-                    if ( index < line.length() ) {
-                        value = line.substring( index );
-                        index = value.indexOf( ' ' );
-                        if ( index > 0 )
-                            value = value.substring( 0, index );
-                        code = Integer.parseInt( value );
-                                        defineEntity( name, (char) code );
-                    }
-                }
-                line = reader.readLine();
-            }
-            is.close();
-        }  catch ( Exception except ) {
-            throw new RuntimeException( "SER003 The resource [" + ENTITIES_RESOURCE + "] could not load: " +
-                                        except.toString() + "\n" + ENTITIES_RESOURCE + "\t" + except.toString());
-        } finally {
-            if ( is != null ) {
-                try {
-                    is.close();
-                } catch ( Exception except ) { }
-            }
-        }
-    }
-    
-
-    /**
-     * Defines a new character reference. The reference's name and value are
-     * supplied. Nothing happens if the character reference is already defined.
-     * <P>
-     * Unlike internal entities, character references are a string to single
-     * character mapping. They are used to map non-ASCII characters both on
-     * parsing and printing, primarily for HTML documents. '&lt;amp;' is an
-     * example of a character reference.
-     *
-     * @param name The entity's name
-     * @param value The entity's value
-     */
-    private static void defineEntity( String name, char value )
-    {
-        if ( _byName.get( name ) == null ) {
-            _byName.put( name, new Character( value ) );
-            _byChar.put( String.valueOf( value ), name );
-        }
-    }
-
-
-    private static void defineElement( String name, int flags )
-    {
-        _elemDefs.put( name, new Integer( flags ) );
-    }
-    
-    
-    private static void defineBoolean( String tagName, String attrName )
-    {
-        defineBoolean( tagName, new String[] { attrName } );
-    }
-    
-    
-    private static void defineBoolean( String tagName, String[] attrNames )
-    {
-        _boolAttrs.put( tagName, attrNames );
-    }
-    
-    
-    private static boolean isElement( String name, int flag )
-    {
-        Integer flags;
-        
-        flags = (Integer) _elemDefs.get( name.toUpperCase() );
-        if ( flags == null )
-            return false;
-        else
-            return ( ( flags.intValue() & flag ) == flag );
-    }
-    
-    
-    static
-    {
-        _elemDefs = new Hashtable();
-        defineElement( "ADDRESS", CLOSE_P );
-        defineElement( "AREA", EMPTY );
-        defineElement( "BASE",  EMPTY | ALLOWED_HEAD );
-        defineElement( "BASEFONT", EMPTY );
-        defineElement( "BLOCKQUOTE", CLOSE_P );
-        defineElement( "BODY", OPT_CLOSING );
-        defineElement( "BR", EMPTY );
-        defineElement( "COL", EMPTY );
-        defineElement( "COLGROUP", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE );
-        defineElement( "DD", OPT_CLOSING | ONLY_OPENING | CLOSE_DD_DT );
-        defineElement( "DIV", CLOSE_P );
-        defineElement( "DL", ELEM_CONTENT | CLOSE_P );
-        defineElement( "DT", OPT_CLOSING | ONLY_OPENING | CLOSE_DD_DT );
-        defineElement( "FIELDSET", CLOSE_P );
-        defineElement( "FORM", CLOSE_P );
-        defineElement( "FRAME", EMPTY | OPT_CLOSING );
-        defineElement( "H1", CLOSE_P );
-        defineElement( "H2", CLOSE_P );
-        defineElement( "H3", CLOSE_P );
-        defineElement( "H4", CLOSE_P );
-        defineElement( "H5", CLOSE_P );
-        defineElement( "H6", CLOSE_P );
-        defineElement( "HEAD", ELEM_CONTENT | OPT_CLOSING );
-        defineElement( "HR", EMPTY | CLOSE_P );
-        defineElement( "HTML", ELEM_CONTENT | OPT_CLOSING );
-        defineElement( "IMG", EMPTY );
-        defineElement( "INPUT", EMPTY );
-        defineElement( "ISINDEX", EMPTY | ALLOWED_HEAD );
-        defineElement( "LI", OPT_CLOSING | ONLY_OPENING | CLOSE_SELF );
-        defineElement( "LINK", EMPTY | ALLOWED_HEAD );
-        defineElement( "MAP", ALLOWED_HEAD );
-        defineElement( "META", EMPTY | ALLOWED_HEAD );
-        defineElement( "OL", ELEM_CONTENT | CLOSE_P );
-        defineElement( "OPTGROUP", ELEM_CONTENT );
-        defineElement( "OPTION", OPT_CLOSING | ONLY_OPENING | CLOSE_SELF );
-        defineElement( "P", OPT_CLOSING | CLOSE_P | CLOSE_SELF );
-        defineElement( "PARAM", EMPTY );
-        defineElement( "PRE", PRESERVE | CLOSE_P );
-        defineElement( "SCRIPT", ALLOWED_HEAD | PRESERVE );
-        defineElement( "NOSCRIPT", ALLOWED_HEAD | PRESERVE );
-        defineElement( "SELECT", ELEM_CONTENT );
-        defineElement( "STYLE", ALLOWED_HEAD | PRESERVE );
-        defineElement( "TABLE", ELEM_CONTENT | CLOSE_P );
-        defineElement( "TBODY", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE );
-        defineElement( "TD", OPT_CLOSING | CLOSE_TH_TD );
-        defineElement( "TEXTAREA", PRESERVE );
-        defineElement( "TFOOT", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE );
-        defineElement( "TH", OPT_CLOSING | CLOSE_TH_TD );
-        defineElement( "THEAD", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE );
-        defineElement( "TITLE", ALLOWED_HEAD );
-        defineElement( "TR", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE );
-        defineElement( "UL", ELEM_CONTENT | CLOSE_P );
-        
-        _boolAttrs = new Hashtable();
-        defineBoolean( "AREA", "href" );
-        defineBoolean( "BUTTON", "disabled" );
-        defineBoolean( "DIR", "compact" );
-        defineBoolean( "DL", "compact" );
-        defineBoolean( "FRAME", "noresize" );
-        defineBoolean( "HR", "noshade" );
-        defineBoolean( "IMAGE", "ismap" );
-        defineBoolean( "INPUT", new String[] { "defaultchecked", "checked", "readonly", "disabled" } );
-        defineBoolean( "LINK", "link" );
-        defineBoolean( "MENU", "compact" );
-        defineBoolean( "OBJECT", "declare" );
-        defineBoolean( "OL", "compact" );
-        defineBoolean( "OPTGROUP", "disabled" );
-        defineBoolean( "OPTION", new String[] { "default-selected", "selected", "disabled" } );
-        defineBoolean( "SCRIPT", "defer" );
-        defineBoolean( "SELECT", new String[] { "multiple", "disabled" } );
-        defineBoolean( "STYLE", "disabled" );
-        defineBoolean( "TD", "nowrap" );
-        defineBoolean( "TH", "nowrap" );
-        defineBoolean( "TEXTAREA", new String[] { "disabled", "readonly" } );
-        defineBoolean( "UL", "compact" );
-        
-        initialize();
-    }
-
-
-
-}
-
diff --git a/src/org/apache/xml/serialize/IndentPrinter.java b/src/org/apache/xml/serialize/IndentPrinter.java
deleted file mode 100644
index 4e1f623..0000000
--- a/src/org/apache/xml/serialize/IndentPrinter.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xml.serialize;
-
-
-import java.io.Writer;
-import java.io.StringWriter;
-import java.io.IOException;
-
-
-/**
- * Extends {@link Printer} and adds support for indentation and line
- * wrapping.
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- */
-class IndentPrinter
-    extends Printer
-{
-
-
-    /**
-     * Holds the currently accumulating text line. This buffer will constantly
-     * be reused by deleting its contents instead of reallocating it.
-     */
-    private StringBuffer    _line;
-
-
-    /**
-     * Holds the currently accumulating text that follows {@link #_line}.
-     * When the end of the part is identified by a call to {@link #printSpace}
-     * or {@link #breakLine}, this part is added to the accumulated line.
-     */
-    private StringBuffer    _text;
-
-
-    /**
-     * Counts how many white spaces come between the accumulated line and the
-     * current accumulated text. Multiple spaces at the end of the a line
-     * will not be printed.
-     */
-    private int             _spaces;
-
-
-    /**
-     * Holds the indentation for the current line that is now accumulating in
-     * memory and will be sent for printing shortly.
-     */
-    private int             _thisIndent;
-    
-    
-    /**
-     * Holds the indentation for the next line to be printed. After this line is
-     * printed, {@link #_nextIndent} is assigned to {@link #_thisIndent}.
-     */
-    private int             _nextIndent;
-
-
-    IndentPrinter( Writer writer, OutputFormat format)
-    {
-        super( writer, format );
-        // Initialize everything for a first/second run.
-        _line = new StringBuffer( 80 );
-        _text = new StringBuffer( 20 );
-        _spaces = 0;
-        _thisIndent = _nextIndent = 0;
-    }
-
-
-    /**
-     * Called by any of the DTD handlers to enter DTD mode.
-     * Once entered, all output will be accumulated in a string
-     * that can be printed as part of the document's DTD.
-     * This method may be called any number of time but will only
-     * have affect the first time it's called. To exist DTD state
-     * and get the accumulated DTD, call {@link #leaveDTD}.
-     */
-    public void enterDTD()
-    {
-        // Can only enter DTD state once. Once we're out of DTD
-        // state, can no longer re-enter it.
-        if ( _dtdWriter == null ) {
-            _line.append( _text );
-            _text = new StringBuffer( 20 );
-            flushLine( false );
-            _dtdWriter = new StringWriter();
-            _docWriter = _writer;
-            _writer = _dtdWriter;
-        }
-    }
-    
-    
-    /**
-     * Called by the root element to leave DTD mode and if any
-     * DTD parts were printer, will return a string with their
-     * textual content.
-     */
-    public String leaveDTD()
-    {
-        // Only works if we're going out of DTD mode.
-        if ( _writer == _dtdWriter ) {
-            _line.append( _text );
-            _text = new StringBuffer( 20 );
-            flushLine( false );
-            _writer = _docWriter;
-            return _dtdWriter.toString();
-        } else
-            return null;
-    }
-    
-    
-    /**
-     * Called to print additional text. Each time this method is called
-     * it accumulates more text. When a space is printed ({@link
-     * #printSpace}) all the accumulated text becomes one part and is
-     * added to the accumulate line. When a line is long enough, it can
-     * be broken at its text boundary.
-     *
-     * @param text The text to print
-     */
-    public void printText( String text )
-    {
-        _text.append( text );
-    }
-    
-    
-    public void printText( StringBuffer text )
-    {
-        _text.append( text );
-    }
-
-
-    public void printText( char ch )
-    {
-        _text.append( ch );
-    }
-
-
-    public void printText( char[] chars, int start, int length )
-    {
-        _text.append( chars, start, length );
-    }
-    
-
-    /**
-     * Called to print a single space between text parts that may be
-     * broken into separate lines. Must not be called to print a space
-     * when preserving spaces. The text accumulated so far with {@link
-     * #printText} will be added to the accumulated line, and a space
-     * separator will be counted. If the line accumulated so far is
-     * long enough, it will be printed.
-     */
-    public void printSpace()
-    {
-        // The line consists of the text accumulated in _line,
-        // followed by one or more spaces as counted by _spaces,
-        // followed by more space accumulated in _text:
-        // -  Text is printed and accumulated into _text.
-        // -  A space is printed, so _text is added to _line and
-        //    a space is counted.
-        // -  More text is printed and accumulated into _text.
-        // -  A space is printed, the previous spaces are added
-        //    to _line, the _text is added to _line, and a new
-        //    space is counted.
-        
-        // If text was accumulated with printText(), then the space
-        // means we have to move that text into the line and
-        // start accumulating new text with printText().
-        if ( _text.length() > 0 ) {
-            // If the text breaks a line bounary, wrap to the next line.
-            // The printed line size consists of the indentation we're going
-            // to use next, the accumulated line so far, some spaces and the
-            // accumulated text so far.
-            if ( _format.getLineWidth() > 0 &&
-                 _thisIndent + _line.length() + _spaces + _text.length() > _format.getLineWidth() ) {
-                flushLine( false );
-                try {
-                    // Print line and new line, then zero the line contents.
-                    _writer.write( _format.getLineSeparator() );
-                } catch ( IOException except ) {
-                    // We don't throw an exception, but hold it
-                    // until the end of the document.
-                    if ( _exception == null )
-                        _exception = except;
-                }
-            }
-            
-            // Add as many spaces as we accumulaed before.
-            // At the end of this loop, _spaces is zero.
-            while ( _spaces > 0 ) {
-                _line.append( ' ' );
-                --_spaces;
-            }
-            _line.append( _text );
-            _text = new StringBuffer( 20 );
-        }
-        // Starting a new word: accumulate the text between the line
-        // and this new word; not a new word: just add another space.
-        ++_spaces;
-    }
-
-
-    /**
-     * Called to print a line consisting of the text accumulated so
-     * far. This is equivalent to calling {@link #printSpace} but
-     * forcing the line to print and starting a new line ({@link
-     * #printSpace} will only start a new line if the current line
-     * is long enough).
-     */
-    public void breakLine()
-    {
-        breakLine( false );
-    }
-
-
-    public void breakLine( boolean preserveSpace )
-    {
-        // Equivalent to calling printSpace and forcing a flushLine.
-        if ( _text.length() > 0 ) {
-            while ( _spaces > 0 ) {
-                _line.append( ' ' );
-                --_spaces;
-            }
-            _line.append( _text );
-            _text = new StringBuffer( 20 );
-        }
-        flushLine( preserveSpace );
-        try {
-            // Print line and new line, then zero the line contents.
-            _writer.write( _format.getLineSeparator() );
-        } catch ( IOException except ) {
-            // We don't throw an exception, but hold it
-            // until the end of the document.
-            if ( _exception == null )
-                _exception = except;
-        }
-    }
-    
-
-    /**
-     * Flushes the line accumulated so far to the writer and get ready
-     * to accumulate the next line. This method is called by {@link
-     * #printText} and {@link #printSpace} when the accumulated line plus
-     * accumulated text are two long to fit on a given line. At the end of
-     * this method {@link #_line} is empty and {@link #_spaces} is zero.
-     */
-    public void flushLine( boolean preserveSpace )
-    {
-        int     indent;
-        
-        if ( _line.length() > 0 ) {
-            try {
-                
-                if ( _format.getIndenting() && ! preserveSpace ) {
-                    // Make sure the indentation does not blow us away.
-                    indent = _thisIndent;
-                    if ( ( 2 * indent ) > _format.getLineWidth() && _format.getLineWidth() > 0 )
-                        indent = _format.getLineWidth() / 2;
-                    // Print the indentation as spaces and set the current
-                    // indentation to the next expected indentation.
-                    while ( indent > 0 ) {
-                        _writer.write( ' ' );
-                        --indent;
-                    }
-                }
-                _thisIndent = _nextIndent;
-                
-                // There is no need to print the spaces at the end of the line,
-                // they are simply stripped and replaced with a single line
-                // separator.
-                _spaces = 0;
-                _writer.write( _line.toString() );
-                
-                _line = new StringBuffer( 40 );
-            } catch ( IOException except ) {
-                // We don't throw an exception, but hold it
-                // until the end of the document.
-                if ( _exception == null )
-                    _exception = except;
-            }
-        }
-    }
-    
-    
-    /**
-     * Flush the output stream. Must be called when done printing
-     * the document, otherwise some text might be buffered.
-     */
-    public void flush()
-    {
-        if ( _line.length() > 0 || _text.length() > 0 )
-            breakLine();
-        try {
-            _writer.flush();
-        } catch ( IOException except ) {
-            // We don't throw an exception, but hold it
-            // until the end of the document.
-            if ( _exception == null )
-                _exception = except;
-        }
-    }
-
-
-    /**
-     * Increment the indentation for the next line.
-     */
-    public void indent()
-    {
-        _nextIndent += _format.getIndent();
-    }
-
-
-    /**
-     * Decrement the indentation for the next line.
-     */
-    public void unindent()
-    {
-        _nextIndent -= _format.getIndent();
-        if ( _nextIndent < 0 )
-            _nextIndent = 0;
-        // If there is no current line and we're de-identing then
-        // this indentation level is actually the next level.
-        if ( ( _line.length() + _spaces + _text.length() ) == 0 )
-            _thisIndent = _nextIndent;
-    }
-
-
-    public int getNextIndent()
-    {
-        return _nextIndent;
-    }
-
-
-    public void setNextIndent( int indent )
-    {
-        _nextIndent = indent;
-    }
-
-
-    public void setThisIndent( int indent )
-    {
-        _thisIndent = indent;
-    }
-
-
-}
diff --git a/src/org/apache/xml/serialize/LineSeparator.java b/src/org/apache/xml/serialize/LineSeparator.java
deleted file mode 100644
index 88e2063..0000000
--- a/src/org/apache/xml/serialize/LineSeparator.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xml.serialize;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio..com">Assaf Arkin</a>
- * @see OutputFormat
- */
-public final class LineSeparator
-{
-    
-    
-    /**
-     * Line separator for Unix systems (<tt>\n</tt>).
-     */
-    public static final String Unix = "\n";
-    
-    
-    /**
-     * Line separator for Windows systems (<tt>\r\n</tt>).
-     */
-    public static final String Windows = "\r\n";
-    
-    
-    /**
-     * Line separator for Macintosh systems (<tt>\r</tt>).
-     */
-    public static final String Macintosh = "\r";
-    
-    
-    /**
-     * Line separator for the Web (<tt>\n</tt>).
-     */
-    public static final String Web = "\n";
-    
-    
-}
-
-
diff --git a/src/org/apache/xml/serialize/Makefile b/src/org/apache/xml/serialize/Makefile
deleted file mode 100644
index c7a329d..0000000
--- a/src/org/apache/xml/serialize/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-# Makefile for directory ./org/apache/xml/serialize
-
-TARGETS=\
-	OutputFormat.class\
-	Method.class\
-	LineSeparator.class\
-	Serializer.class\
-	DOMSerializer.class\
-	BaseMarkupSerializer.class\
-	XMLSerializer.class\
-	HTMLSerializer.class\
-	XHTMLSerializer.class\
-	TextSerializer.class\
-	ElementState.class\
-	HTMLdtd.class\
-	SerializerFactory.class\
-	SerializerFactoryImpl.class
-
-DIRS =
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/apache/xml/serialize/Method.java b/src/org/apache/xml/serialize/Method.java
deleted file mode 100644
index 2b27a57..0000000
--- a/src/org/apache/xml/serialize/Method.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xml.serialize;
-
-
-/**
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- * @see OutputFormat
- */
-public final class Method
-{
-    
-    
-    /**
-     * The output method for XML documents.
-     */
-    public static final String XML = "xml";
-    
-    
-    /**
-     * The output method for HTML documents.
-     */
-    public static final String HTML = "html";
-    
-    
-    /**
-     * The output method for HTML documents as XHTML.
-     */
-    public static final String XHTML = "xhtml";
-    
-    
-    /**
-     * The output method for text documents.
-     */
-    public static final String TEXT = "text";
-    
-    
-    /**
-     * The output method for FO documents as PDF.
-     */
-    public static final String FOP = "fop";
-    
-    
-}
-
-
diff --git a/src/org/apache/xml/serialize/OutputFormat.java b/src/org/apache/xml/serialize/OutputFormat.java
deleted file mode 100644
index 70d58b4..0000000
--- a/src/org/apache/xml/serialize/OutputFormat.java
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-// Aug 21, 2000:
-//  Added ability to omit DOCTYPE declaration.
-//  Reported by Lars Martin <lars@smb-tec.com>
-// Aug 25, 2000:
-//  Added ability to omit comments.
-//  Contributed by Anupam Bagchi <abagchi@jtcsv.com>
-
-
-package org.apache.xml.serialize;
-
-
-import java.util.Hashtable;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.DocumentType;
-import org.w3c.dom.Node;
-import org.w3c.dom.html.HTMLDocument;
-
-
-/**
- * Specifies an output format to control the serializer. Based on the
- * XSLT specification for output format, plus additional parameters.
- * Used to select the suitable serializer and determine how the
- * document should be formatted on output.
- * <p>
- * The two interesting constructors are:
- * <ul>
- * <li>{@link #OutputFormat(String,String,boolean)} creates a format
- *  for the specified method (XML, HTML, Text, etc), encoding and indentation
- * <li>{@link #OutputFormat(Document,String,boolean)} creates a format
- *  compatible with the document type (XML, HTML, Text, etc), encoding and
- *  indentation
- * </ul>
- *
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- *         <a href="mailto:visco@intalio.com">Keith Visco</a>
- * @see Serializer
- * @see Method
- * @see LineSeparator
- */
-public class OutputFormat
-{
-
-
-    public static class DTD
-    {
-
-        /**
-         * Public identifier for HTML document type.
-         */
-        public static final String HTMLPublicId = "-//W3C//DTD HTML 4.0//EN";
-
-        /**
-         * System identifier for HTML document type.
-         */
-        public static final String HTMLSystemId =
-            "http://www.w3.org/TR/WD-html-in-xml/DTD/xhtml1-strict.dtd";
-
-        /**
-         * Public identifier for XHTML document type.
-         */
-        public static final String XHTMLPublicId =
-            "-//W3C//DTD XHTML 1.0 Strict//EN";
-
-        /**
-         * System identifier for XHTML document type.
-         */
-        public static final String XHTMLSystemId =
-            "http://www.w3.org/TR/WD-html-in-xml/DTD/xhtml1-strict.dtd";
-
-    }
-
-
-    public static class Defaults
-    {
-
-        /**
-         * If indentation is turned on, the default identation
-         * level is 4.
-         *
-         * @see #setIndenting(boolean)
-         */
-        public static final int Indent = 4;
-
-        /**
-         * The default encoding for Web documents it UTF-8.
-         *
-         * @see #getEncoding()
-         */
-        public static final String Encoding = "UTF-8";
-
-        /**
-         * The default line width at which to break long lines
-         * when identing. This is set to 72.
-         */
-        public static final int LineWidth = 72;
-
-    }
-
-
-    /**
-     * Holds the output method specified for this document,
-     * or null if no method was specified.
-     */
-    private String _method;
-
-
-    /**
-     * Specifies the version of the output method.
-     */
-    private String _version;
-
-
-    /**
-     * The indentation level, or zero if no indentation
-     * was requested.
-     */
-    private int _indent = 0;
-
-
-    /**
-     * The encoding to use, if an input stream is used.
-     * The default is always UTF-8.
-     */
-    private String _encoding = Defaults.Encoding;
-
-
-    /**
-     * The specified media type or null.
-     */
-    private String _mediaType;
-
-
-    /**
-     * The specified document type system identifier, or null.
-     */
-    private String _doctypeSystem;
-
-
-    /**
-     * The specified document type public identifier, or null.
-     */
-    private String _doctypePublic;
-
-
-    /**
-     * Ture if the XML declaration should be ommited;
-     */
-    private boolean _omitXmlDeclaration = false;
-
-
-    /**
-     * Ture if the DOCTYPE declaration should be ommited;
-     */
-    private boolean _omitDoctype = false;
-
-
-    /**
-<<<<<<< OutputFormat.java
-     * Ture if comments should be ommited;
-     */
-    private boolean _omitComments = false;
-
-
-    /**
-     * Ture if the comments should be ommited;
-     */
-    private boolean _stripComments = false;
-
-
-    /**
-     * True if the document type should be marked as standalone.
-     */
-    private boolean _standalone = false;
-
-
-    /**
-     * List of element tag names whose text node children must
-     * be output as CDATA.
-     */
-    private String[] _cdataElements;
-
-
-    /**
-     * List of element tag names whose text node children must
-     * be output unescaped.
-     */
-    private String[] _nonEscapingElements;
-
-
-    /**
-     * The selected line separator.
-     */
-    private String _lineSeparator = LineSeparator.Web;
-
-
-    /**
-     * The line width at which to wrap long lines when indenting.
-     */
-    private int _lineWidth = Defaults.LineWidth;
-
-
-    /**
-     * True if spaces should be preserved in elements that do not
-     * specify otherwise, or specify the default behavior.
-     */
-    private boolean _preserve = false;
-
-
-
-    /**
-     * Constructs a new output format with the default values.
-     */
-    public OutputFormat()
-    {
-    }
-
-
-    /**
-     * Constructs a new output format with the default values for
-     * the specified method and encoding. If <tt>indent</tt>
-     * is true, the document will be pretty printed with the default
-     * indentation level and default line wrapping.
-     *
-     * @param method The specified output method
-     * @param encoding The specified encoding
-     * @param indenting True for pretty printing
-     * @see #setEncoding
-     * @see #setIndenting
-     * @see #setMethod
-     */
-    public OutputFormat( String method, String encoding, boolean indenting )
-    {
-        setMethod( method );
-        setEncoding( encoding );
-        setIndenting( indenting );
-    }
-
-
-    /**
-     * Constructs a new output format with the proper method,
-     * document type identifiers and media type for the specified
-     * document.
-     *
-     * @param doc The document to output
-     * @see #whichMethod
-     */
-    public OutputFormat( Document doc )
-    {
-        setMethod( whichMethod( doc ) );
-        setDoctype( whichDoctypePublic( doc ), whichDoctypeSystem( doc ) );
-        setMediaType( whichMediaType( getMethod() ) );
-    }
-
-
-    /**
-     * Constructs a new output format with the proper method,
-     * document type identifiers and media type for the specified
-     * document, and with the specified encoding. If <tt>indent</tt>
-     * is true, the document will be pretty printed with the default
-     * indentation level and default line wrapping.
-     *
-     * @param doc The document to output
-     * @param encoding The specified encoding
-     * @param indenting True for pretty printing
-     * @see #setEncoding
-     * @see #setIndenting
-     * @see #whichMethod
-     */
-    public OutputFormat( Document doc, String encoding, boolean indenting )
-    {
-        this( doc );
-        setEncoding( encoding );
-        setIndenting( indenting );
-    }
-
-
-    /**
-     * Returns the method specified for this output format.
-     * Typically the method will be <tt>xml</tt>, <tt>html</tt>
-     * or <tt>text</tt>, but it might be other values.
-     * If no method was specified, null will be returned
-     * and the most suitable method will be determined for
-     * the document by calling {@link #whichMethod}.
-     *
-     * @return The specified output method, or null
-     */
-    public String getMethod()
-    {
-        return _method;
-    }
-
-
-    /**
-     * Sets the method for this output format.
-     *
-     * @see #getMethod
-     * @param method The output method, or null
-     */
-    public void setMethod( String method )
-    {
-        _method = method;
-    }
-
-
-    /**
-     * Returns the version for this output method.
-     * If no version was specified, will return null
-     * and the default version number will be used.
-     * If the serializerr does not support that particular
-     * version, it should default to a supported version.
-     *
-     * @return The specified method version, or null
-     */
-    public String getVersion()
-    {
-        return _version;
-    }
-
-
-    /**
-     * Sets the version for this output method.
-     * For XML the value would be "1.0", for HTML
-     * it would be "4.0".
-     *
-     * @see #getVersion
-     * @param version The output method version, or null
-     */
-    public void setVersion( String version )
-    {
-        _version = version;
-    }
-
-
-    /**
-     * Returns the indentation specified. If no indentation
-     * was specified, zero is returned and the document
-     * should not be indented.
-     *
-     * @return The indentation or zero
-     * @see #setIndenting
-     */
-    public int getIndent()
-    {
-        return _indent;
-    }
-
-
-    /**
-     * Returns true if indentation was specified.
-     */
-    public boolean getIndenting()
-    {
-        return ( _indent > 0 );
-    }
-
-
-    /**
-     * Sets the indentation. The document will not be
-     * indented if the indentation is set to zero.
-     * Calling {@link #setIndenting} will reset this
-     * value to zero (off) or the default (on).
-     *
-     * @param indent The indentation, or zero
-     */
-    public void setIndent( int indent )
-    {
-        if ( indent < 0 )
-            _indent = 0;
-        else
-            _indent = indent;
-    }
-
-
-    /**
-     * Sets the indentation on and off. When set on, the default
-     * indentation level and default line wrapping is used
-     * (see {@link #DEFAULT_INDENT} and {@link #DEFAULT_LINE_WIDTH}).
-     * To specify a different indentation level or line wrapping,
-     * use {@link #setIndent} and {@link #setLineWidth}.
-     *
-     * @param on True if indentation should be on
-     */
-    public void setIndenting( boolean on )
-    {
-        if ( on ) {
-            _indent = Defaults.Indent;
-            _lineWidth = Defaults.LineWidth;
-        } else {
-            _indent = 0;
-            _lineWidth = 0;
-        }
-    }
-
-
-    /**
-     * Returns the specified encoding. If no encoding was
-     * specified, the default is always "UTF-8".
-     *
-     * @return The encoding
-     */
-    public String getEncoding()
-    {
-        return _encoding;
-    }
-
-
-    /**
-     * Sets the encoding for this output method. If no
-     * encoding was specified, the default is always "UTF-8".
-     * Make sure the encoding is compatible with the one
-     * used by the {@link java.io.Writer}.
-     *
-     * @see #getEncoding
-     * @param encoding The encoding, or null
-     */
-    public void setEncoding( String encoding )
-    {
-        _encoding = encoding;
-    }
-
-
-    /**
-     * Returns the specified media type, or null.
-     * To determine the media type based on the
-     * document type, use {@link #whichMediaType}.
-     *
-     * @return The specified media type, or null
-     */
-    public String getMediaType()
-    {
-        return _mediaType;
-    }
-
-
-    /**
-     * Sets the media type.
-     *
-     * @see #getMediaType
-     * @param mediaType The specified media type
-     */
-    public void setMediaType( String mediaType )
-    {
-        _mediaType = mediaType;
-    }
-
-
-    /**
-     * Sets the document type public and system identifiers.
-     * Required only if the DOM Document or SAX events do not
-     * specify the document type, and one must be present in
-     * the serialized document. Any document type specified
-     * by the DOM Document or SAX events will override these
-     * values.
-     *
-     * @param publicId The public identifier, or null
-     * @param systemId The system identifier, or null
-     */
-    public void setDoctype( String publicId, String systemId )
-    {
-        _doctypePublic = publicId;
-        _doctypeSystem = systemId;
-    }
-
-
-    /**
-     * Returns the specified document type public identifier,
-     * or null.
-     */
-    public String getDoctypePublic()
-    {
-        return _doctypePublic;
-    }
-
-
-    /**
-     * Returns the specified document type system identifier,
-     * or null.
-     */
-    public String getDoctypeSystem()
-    {
-        return _doctypeSystem;
-    }
-
-
-    /**
-     * Returns true if comments should be ommited.
-     * The default is false.
-     */
-    public boolean getOmitComments()
-    {
-        return _omitComments;
-    }
-
-
-    /**
-     * Sets comment omitting on and off.
-     *
-     * @param omit True if comments should be ommited
-     */
-    public void setOmitComments( boolean omit )
-    {
-        _omitComments = omit;
-    }
-
-
-    /**
-     * Returns true if the DOCTYPE declaration should
-     * be ommited. The default is false.
-     */
-    public boolean getOmitDocumentType()
-    {
-        return _omitDoctype;
-    }
-
-
-    /**
-     * Sets DOCTYPE declaration omitting on and off.
-     *
-     * @param omit True if DOCTYPE declaration should be ommited
-     */
-    public void setOmitDocumentType( boolean omit )
-    {
-        _omitDoctype = omit;
-    }
-
-
-    /**
-     * Returns true if the XML document declaration should
-     * be ommited. The default is false.
-     */
-    public boolean getOmitXMLDeclaration()
-    {
-        return _omitXmlDeclaration;
-    }
-
-
-    /**
-     * Sets XML declaration omitting on and off.
-     *
-     * @param omit True if XML declaration should be ommited
-     */
-    public void setOmitXMLDeclaration( boolean omit )
-    {
-        _omitXmlDeclaration = omit;
-    }
-
-
-    /**
-     * Returns true if the document type is standalone.
-     * The default is false.
-     */
-    public boolean getStandalone()
-    {
-        return _standalone;
-    }
-
-
-    /**
-     * Sets document DTD standalone. The public and system
-     * identifiers must be null for the document to be
-     * serialized as standalone.
-     *
-     * @param standalone True if document DTD is standalone
-     */
-    public void setStandalone( boolean standalone )
-    {
-        _standalone = standalone;
-    }
-
-
-    /**
-     * Returns a list of all the elements whose text node children
-     * should be output as CDATA, or null if no such elements were
-     * specified.
-     */
-    public String[] getCDataElements()
-    {
-        return _cdataElements;
-    }
-
-
-    /**
-     * Returns true if the text node children of the given elements
-     * should be output as CDATA.
-     *
-     * @param tagName The element's tag name
-     * @return True if should serialize as CDATA
-     */
-    public boolean isCDataElement( String tagName )
-    {
-        int i;
-
-        if ( _cdataElements == null )
-            return false;
-        for ( i = 0 ; i < _cdataElements.length ; ++i )
-            if ( _cdataElements[ i ].equals( tagName ) )
-                return true;
-        return false;
-    }
-
-
-    /**
-     * Sets the list of elements for which text node children
-     * should be output as CDATA.
-     *
-     * @param cdataElements List of CDATA element tag names
-     */
-    public void setCDataElements( String[] cdataElements )
-    {
-        _cdataElements = cdataElements;
-    }
-
-
-    /**
-     * Returns a list of all the elements whose text node children
-     * should be output unescaped (no character references), or null
-     * if no such elements were specified.
-     */
-    public String[] getNonEscapingElements()
-    {
-        return _nonEscapingElements;
-    }
-
-
-    /**
-     * Returns true if the text node children of the given elements
-     * should be output unescaped.
-     *
-     * @param tagName The element's tag name
-     * @return True if should serialize unescaped
-     */
-    public boolean isNonEscapingElement( String tagName )
-    {
-        int i;
-
-        if ( _nonEscapingElements == null )
-            return false;
-        for ( i = 0 ; i < _nonEscapingElements.length ; ++i )
-            if ( _nonEscapingElements[ i ].equals( tagName ) )
-                return true;
-        return false;
-    }
-
-
-    /**
-     * Sets the list of elements for which text node children
-     * should be output unescaped (no character references).
-     *
-     * @param nonEscapingElements List of unescaped element tag names
-     */
-    public void setNonEscapingElements( String[] nonEscapingElements )
-    {
-        _nonEscapingElements = nonEscapingElements;
-    }
-
-
-
-    /**
-     * Returns a specific line separator to use. The default is the
-     * Web line separator (<tt>\n</tt>). A string is returned to
-     * support double codes (CR + LF).
-     *
-     * @return The specified line separator
-     */
-    public String getLineSeparator()
-    {
-        return _lineSeparator;
-    }
-
-
-    /**
-     * Sets the line separator. The default is the Web line separator
-     * (<tt>\n</tt>). The machine's line separator can be obtained
-     * from the system property <tt>line.separator</tt>, but is only
-     * useful if the document is edited on machines of the same type.
-     * For general documents, use the Web line separator.
-     *
-     * @param lineSeparator The specified line separator
-     */
-    public void setLineSeparator( String lineSeparator )
-    {
-        if ( lineSeparator == null )
-            _lineSeparator =  LineSeparator.Web;
-        else
-            _lineSeparator = lineSeparator;
-    }
-
-
-    /**
-     * Returns true if the default behavior for this format is to
-     * preserve spaces. All elements that do not specify otherwise
-     * or specify the default behavior will be formatted based on
-     * this rule. All elements that specify space preserving will
-     * always preserve space.
-     */
-    public boolean getPreserveSpace()
-    {
-        return _preserve;
-    }
-
-
-    /**
-     * Sets space preserving as the default behavior. The default is
-     * space stripping and all elements that do not specify otherwise
-     * or use the default value will not preserve spaces.
-     *
-     * @param preserve True if spaces should be preserved
-     */
-    public void setPreserveSpace( boolean preserve )
-    {
-        _preserve = preserve;
-    }
-
-
-    /**
-     * Return the selected line width for breaking up long lines.
-     * When indenting, and only when indenting, long lines will be
-     * broken at space boundaries based on this line width.
-     * No line wrapping occurs if this value is zero.
-     */
-    public int getLineWidth()
-    {
-        return _lineWidth;
-    }
-
-
-    /**
-     * Sets the line width. If zero then no line wrapping will
-     * occur. Calling {@link #setIndenting} will reset this
-     * value to zero (off) or the default (on).
-     *
-     * @param lineWidth The line width to use, zero for default
-     * @see #getLineWidth
-     * @see #setIndenting
-     */
-    public void setLineWidth( int lineWidth )
-    {
-        if ( lineWidth <= 0 )
-            _lineWidth = 0;
-        else
-            _lineWidth = lineWidth;
-    }
-
-
-    /**
-     * Returns the last printable character based on the selected
-     * encoding. Control characters and non-printable characters
-     * are always printed as character references.
-     */
-    public char getLastPrintable()
-    {
-        if ( getEncoding() != null &&
-             ( getEncoding().equalsIgnoreCase( "ASCII" ) ) )
-            return 0xFF;
-        else
-            return 0xFFFF;
-    }
-
-
-    /**
-     * Determine the output method for the specified document.
-     * If the document is an instance of {@link org.w3c.dom.html.HTMLDocument}
-     * then the method is said to be <tt>html</tt>. If the root
-     * element is 'html' and all text nodes preceding the root
-     * element are all whitespace, then the method is said to be
-     * <tt>html</tt>. Otherwise the method is <tt>xml</tt>.
-     *
-     * @param doc The document to check
-     * @return The suitable method
-     */
-    public static String whichMethod( Document doc )
-    {
-        Node    node;
-        String  value;
-        int     i;
-
-        // If document is derived from HTMLDocument then the default
-        // method is html.
-        if ( doc instanceof HTMLDocument )
-            return Method.HTML;
-
-        // Lookup the root element and the text nodes preceding it.
-        // If root element is html and all text nodes contain whitespace
-        // only, the method is html.
-
-        // FIXME (SM) should we care about namespaces here?
-
-        node = doc.getFirstChild();
-        while (node != null) {
-            // If the root element is html, the method is html.
-            if ( node.getNodeType() == Node.ELEMENT_NODE ) {
-                if ( node.getNodeName().equalsIgnoreCase( "html" ) ) {
-                    return Method.HTML;
-                } else if ( node.getNodeName().equalsIgnoreCase( "root" ) ) {
-                    return Method.FOP;
-                } else {
-                    return Method.XML;
-                }
-            } else if ( node.getNodeType() == Node.TEXT_NODE ) {
-                // If a text node preceding the root element contains
-                // only whitespace, this might be html, otherwise it's
-                // definitely xml.
-                value = node.getNodeValue();
-                for ( i = 0 ; i < value.length() ; ++i )
-                    if ( value.charAt( i ) != 0x20 && value.charAt( i ) != 0x0A &&
-                         value.charAt( i ) != 0x09 && value.charAt( i ) != 0x0D )
-                        return Method.XML;
-            }
-            node = node.getNextSibling();
-        }
-        // Anything else, the method is xml.
-        return Method.XML;
-    }
-
-
-    /**
-     * Returns the document type public identifier
-     * specified for this document, or null.
-     */
-    public static String whichDoctypePublic( Document doc )
-    {
-        DocumentType doctype;
-
-        /* XXX  Delayed until DOM Level 2 is introduced into the code base
-           doctype = doc.getDoctype();
-           if ( doctype != null ) {
-           // Note on catch: DOM Level 1 does not specify this method
-           // and the code will throw a NoSuchMethodError
-           try {
-           return doctype.getPublicID();
-           } catch ( Error except ) {  }
-           }
-        */
-        if ( doc instanceof HTMLDocument )
-            return DTD.XHTMLPublicId;
-        return null;
-    }
-
-
-    /**
-     * Returns the document type system identifier
-     * specified for this document, or null.
-     */
-    public static String whichDoctypeSystem( Document doc )
-    {
-        DocumentType doctype;
-
-        /* XXX  Delayed until DOM Level 2 is introduced into the code base
-           doctype = doc.getDoctype();
-           if ( doctype != null ) {
-           // Note on catch: DOM Level 1 does not specify this method
-           // and the code will throw a NoSuchMethodError
-           try {
-           return doctype.getSystemID();
-           } catch ( Error except ) { }
-           }
-        */
-        if ( doc instanceof HTMLDocument )
-            return DTD.XHTMLSystemId;
-        return null;
-    }
-
-
-    /**
-     * Returns the suitable media format for a document
-     * output with the specified method.
-     */
-    public static String whichMediaType( String method )
-    {
-        if ( method.equalsIgnoreCase( Method.XML ) )
-            return "text/xml";
-        if ( method.equalsIgnoreCase( Method.HTML ) )
-            return "text/html";
-        if ( method.equalsIgnoreCase( Method.XHTML ) )
-            return "text/html";
-        if ( method.equalsIgnoreCase( Method.TEXT ) )
-            return "text/plain";
-        if ( method.equalsIgnoreCase( Method.FOP ) )
-            return "application/pdf";
-        return null;
-    }
-
-
-}
-
diff --git a/src/org/apache/xml/serialize/Printer.java b/src/org/apache/xml/serialize/Printer.java
deleted file mode 100644
index 988b77b..0000000
--- a/src/org/apache/xml/serialize/Printer.java
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xml.serialize;
-
-
-import java.io.Writer;
-import java.io.StringWriter;
-import java.io.IOException;
-
-
-/**
- * The printer is responsible for sending text to the output stream
- * or writer. This class performs direct writing for efficiency.
- * {@link IndentPrinter} supports indentation and line wrapping by
- * extending this class.
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- */
-public class Printer
-{
-
-
-    /**
-     * The output format associated with this serializer. This will never
-     * be a null reference. If no format was passed to the constructor,
-     * the default one for this document type will be used. The format
-     * object is never changed by the serializer.
-     */
-    protected final OutputFormat _format;
-
-
-    /**
-     * The writer to which the document is written.
-     */
-    protected Writer             _writer;
-
-
-    /**
-     * The DTD writer. When we switch to DTD mode, all output is
-     * accumulated in this DTD writer. When we switch out of it,
-     * the output is obtained as a string. Must not be reset to
-     * null until we're done with the document.
-     */
-    protected StringWriter       _dtdWriter;
-
-
-    /**
-     * Holds a reference to the document writer while we are
-     * in DTD mode.
-     */
-    protected Writer          _docWriter;
-
-
-    /**
-     * Holds the exception thrown by the serializer.  Exceptions do not cause
-     * the serializer to quit, but are held and one is thrown at the end.
-     */
-    protected IOException     _exception;
-
-
-    /**
-     * The size of the output buffer.
-     */
-    private static final int BufferSize = 4096;
-
-
-    /**
-     * Output buffer.
-     */
-    private final char[]  _buffer = new char[ BufferSize ];
-
-
-    /**
-     * Position within the output buffer.
-     */
-    private int           _pos = 0;
-
-
-    public Printer( Writer writer, OutputFormat format)
-    {
-        _writer = writer;
-        _format = format;
-        _exception = null;
-        _dtdWriter = null;
-        _docWriter = null;
-        _pos = 0;
-    }
-
-
-    public IOException getException()
-    {
-        return _exception;
-    }
-
-
-    /**
-     * Called by any of the DTD handlers to enter DTD mode.
-     * Once entered, all output will be accumulated in a string
-     * that can be printed as part of the document's DTD.
-     * This method may be called any number of time but will only
-     * have affect the first time it's called. To exist DTD state
-     * and get the accumulated DTD, call {@link #leaveDTD}.
-     */
-    public void enterDTD()
-    {
-        // Can only enter DTD state once. Once we're out of DTD
-        // state, can no longer re-enter it.
-        if ( _dtdWriter == null ) {
-            flushLine( false );
-            _dtdWriter = new StringWriter();
-            _docWriter = _writer;
-            _writer = _dtdWriter;
-        }
-    }
-    
-    
-    /**
-     * Called by the root element to leave DTD mode and if any
-     * DTD parts were printer, will return a string with their
-     * textual content.
-     */
-    public String leaveDTD()
-    {
-        // Only works if we're going out of DTD mode.
-        if ( _writer == _dtdWriter ) {
-            flushLine( false );
-            _writer = _docWriter;
-            return _dtdWriter.toString();
-        } else
-            return null;
-    }
-    
-    
-    public void printText( String text )
-    {
-        try {
-            int length = text.length();
-            for ( int i = 0 ; i < length ; ++i ) { 
-                if ( _pos == BufferSize ) {
-                    _writer.write( _buffer );
-                    _pos = 0;
-                }
-                _buffer[ _pos ] = text.charAt( i );
-                ++_pos;
-            }
-        } catch ( IOException except ) {
-            // We don't throw an exception, but hold it
-            // until the end of the document.
-            if ( _exception == null )
-                _exception = except;
-        }
-    }
-    
-    
-    public void printText( StringBuffer text )
-    {
-        try {
-            int length = text.length();
-            for ( int i = 0 ; i < length ; ++i ) { 
-                if ( _pos == BufferSize ) {
-                    _writer.write( _buffer );
-                    _pos = 0;
-                }
-                _buffer[ _pos ] = text.charAt( i );
-                ++_pos;
-            }
-        } catch ( IOException except ) {
-            // We don't throw an exception, but hold it
-            // until the end of the document.
-            if ( _exception == null )
-                _exception = except;
-        }
-    }
-
-
-    public void printText( char[] chars, int start, int length )
-    {
-        try {
-            while ( length-- > 0 ) {
-                if ( _pos == BufferSize ) {
-                    _writer.write( _buffer );
-                    _pos = 0;
-                }
-                _buffer[ _pos ] = chars[ start ];
-                ++start;
-                ++_pos;
-            }
-        } catch ( IOException except ) {
-            // We don't throw an exception, but hold it
-            // until the end of the document.
-            if ( _exception == null )
-                _exception = except;
-        }
-    }
-    
-
-    public void printText( char ch )
-    {
-        try {
-            if ( _pos == BufferSize ) {
-                _writer.write( _buffer );
-                _pos = 0;
-            }
-            _buffer[ _pos ] = ch;
-            ++_pos;
-        } catch ( IOException except ) {
-            // We don't throw an exception, but hold it
-            // until the end of the document.
-            if ( _exception == null )
-                _exception = except;
-        }
-    }
-
-
-    public void printSpace()
-    {
-        try {
-            if ( _pos == BufferSize ) {
-                _writer.write( _buffer );
-                _pos = 0;
-            }
-            _buffer[ _pos ] = ' ';
-            ++_pos;
-        } catch ( IOException except ) {
-            // We don't throw an exception, but hold it
-            // until the end of the document.
-            if ( _exception == null )
-                _exception = except;
-        }
-    }
-
-
-    public void breakLine()
-    {
-        try {
-            if ( _pos == BufferSize ) {
-                _writer.write( _buffer );
-                _pos = 0;
-            }
-            _buffer[ _pos ] = '\n';
-            ++_pos;
-        } catch ( IOException except ) {
-            // We don't throw an exception, but hold it
-            // until the end of the document.
-            if ( _exception == null )
-                _exception = except;
-        }
-    }
-
-
-    public void breakLine( boolean preserveSpace )
-    {
-        breakLine();
-    }
-    
-
-    public void flushLine( boolean preserveSpace )
-    {
-        // NOOP
-    }
-    
-    
-    /**
-     * Flush the output stream. Must be called when done printing
-     * the document, otherwise some text might be buffered.
-     */
-    public void flush()
-    {
-        try {
-            _writer.write( _buffer, 0, _pos );
-            _writer.flush();
-        } catch ( IOException except ) {
-            // We don't throw an exception, but hold it
-            // until the end of the document.
-            if ( _exception == null )
-                _exception = except;
-        }
-        _pos = 0;
-    }
-
-
-    public void indent()
-    {
-        // NOOP
-    }
-
-
-    public void unindent()
-    {
-        // NOOP
-    }
-
-
-    public int getNextIndent()
-    {
-        return 0;
-    }
-
-
-    public void setNextIndent( int indent )
-    {
-    }
-
-
-    public void setThisIndent( int indent )
-    {
-    }
-
-
-}
diff --git a/src/org/apache/xml/serialize/Serializer.java b/src/org/apache/xml/serialize/Serializer.java
deleted file mode 100644
index c91f3dd..0000000
--- a/src/org/apache/xml/serialize/Serializer.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xml.serialize;
-
-
-import java.io.Writer;
-import java.io.OutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-
-import org.w3c.dom.Element;
-import org.w3c.dom.Document;
-import org.xml.sax.DocumentHandler;
-import org.xml.sax.ContentHandler;
-
-
-/**
- * Interface for a DOM serializer implementation, factory for DOM and SAX
- * serializers, and static methods for serializing DOM documents.
- * <p>
- * To serialize a document using SAX events, create a compatible serializer
- * using {@link #makeSAXSerializer} and pass it around as a {@link
- * DocumentHandler}. If an I/O error occurs while serializing, it will
- * be thrown by {@link DocumentHandler#endDocument}. The SAX serializer
- * may also be used as {@link DTDHandler}, {@link DeclHandler} and
- * {@link LexicalHandler}.
- * <p>
- * To serialize a DOM document or DOM element, create a compatible
- * serializer using {@link #makeSerializer} and call it's {@link
- * #serialize(Document)} or {@link #serialize(Element)} methods.
- * Both methods would produce a full XML document, to serizlie only
- * the portion of the document use {@link OutputFormat#setOmitXMLDeclaration}
- * and specify no document type.
- * <p>
- * The convenience method {@link #serialize(Document,Writer,OutputFormat)}
- * creates a serializer and calls {@link #serizlie(Document)} on that
- * serialized.
- * <p>
- * The {@link OutputFormat} dictates what underlying serialized is used
- * to serialize the document based on the specified method. If the output
- * format or method are missing, the default is an XML serializer with
- * UTF-8 encoding and now indentation.
- * 
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- * @author <a href="mailto:Scott_Boag/CAM/Lotus@lotus.com">Scott Boag</a>
- * @see DocumentHandler
- * @see ContentHandler
- * @see OutputFormat
- * @see DOMSerializer
- */
-public interface Serializer
-{
-
-
-    /**
-     * Specifies an output stream to which the document should be
-     * serialized. This method should not be called while the
-     * serializer is in the process of serializing a document.
-     */
-    public void setOutputByteStream(OutputStream output);
-    
-
-    /**
-     * Specifies a writer to which the document should be serialized.
-     * This method should not be called while the serializer is in
-     * the process of serializing a document.
-     */
-    public void setOutputCharStream( Writer output );
-
-
-    /**
-     * Specifies an output format for this serializer. It the
-     * serializer has already been associated with an output format,
-     * it will switch to the new format. This method should not be
-     * called while the serializer is in the process of serializing
-     * a document.
-     *
-     * @param format The output format to use
-     */
-    public void setOutputFormat( OutputFormat format );
-
-
-    /**
-     * Return a {@link DocumentHandler} interface into this serializer.
-     * If the serializer does not support the {@link DocumentHandler}
-     * interface, it should return null.
-     */
-    public DocumentHandler asDocumentHandler()
-        throws IOException;
-
-
-    /**
-     * Return a {@link ContentHandler} interface into this serializer.
-     * If the serializer does not support the {@link ContentHandler}
-     * interface, it should return null.
-     */
-    public ContentHandler asContentHandler()
-        throws IOException;
-
-
-    /**
-     * Return a {@link DOMSerializer} interface into this serializer.
-     * If the serializer does not support the {@link DOMSerializer}
-     * interface, it should return null.
-     */
-    public DOMSerializer asDOMSerializer()
-        throws IOException;
-
-
-}
-
-
-
-
-
diff --git a/src/org/apache/xml/serialize/SerializerFactory.java b/src/org/apache/xml/serialize/SerializerFactory.java
deleted file mode 100644
index 1534cc0..0000000
--- a/src/org/apache/xml/serialize/SerializerFactory.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xml.serialize;
-
-
-import java.io.OutputStream;
-import java.io.Writer;
-import java.io.UnsupportedEncodingException;
-import java.util.Hashtable;
-import java.util.StringTokenizer;
-
-
-/**
- *
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:Scott_Boag/CAM/Lotus@lotus.com">Scott Boag</a>
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- */
-public abstract class SerializerFactory
-{
-
-
-    public static final String FactoriesProperty = "org.apache.xml.serialize.factories";
-
-
-    private static Hashtable  _factories = new Hashtable();
-
-
-    static
-    {
-        SerializerFactory factory;
-        String            list;
-        StringTokenizer   token;
-        String            className;
-        
-        // The default factories are always registered first,
-        // any factory specified in the properties file and supporting
-        // the same method will override the default factory.
-        factory =  new SerializerFactoryImpl( Method.XML );
-        registerSerializerFactory( factory );
-        factory =  new SerializerFactoryImpl( Method.HTML );
-        registerSerializerFactory( factory );
-        factory =  new SerializerFactoryImpl( Method.XHTML );
-        registerSerializerFactory( factory );
-        factory =  new SerializerFactoryImpl( Method.TEXT );
-        registerSerializerFactory( factory );
-        
-        list = System.getProperty( FactoriesProperty );
-        if ( list != null ) {
-            token = new StringTokenizer( list, " ;,:" );
-            while ( token.hasMoreTokens() ) {
-                className = token.nextToken();
-                try {
-                    factory = (SerializerFactory) Class.forName( className ).newInstance();
-                    if ( _factories.contains( factory.getSupportedMethod() ) )
-                        _factories.put( factory.getSupportedMethod(), factory );
-                } catch ( Exception except ) { }
-            }
-        }
-    }
-
-
-    /**
-     * Register a serializer factory, keyed by the given
-     * method string.
-     */
-    public static void registerSerializerFactory( SerializerFactory factory )
-    {
-        String method;
-        
-        synchronized ( _factories ) {
-            method = factory.getSupportedMethod();
-            _factories.put( method, factory );
-        }
-    }
-
-
-    /**
-     * Register a serializer factory, keyed by the given
-     * method string.
-     */
-    public static SerializerFactory getSerializerFactory( String method )
-    {
-        return (SerializerFactory) _factories.get( method );
-    }
-
-
-    /**
-     * Returns the method supported by this factory and used to register
-     * the factory. This call is required so factories can be added from
-     * a properties file by knowing only the class name. This method is
-     * protected, it is only required by this class but must be implemented
-     * in derived classes.
-     */
-    protected abstract String getSupportedMethod();
-    
-
-    /**
-     * Create a new serializer based on the {@link OutputFormat}.
-     * If this method is used to create the serializer, the {@link
-     * Serializer#setOutputByteStream} or {@link Serializer#setOutputCharStream}
-     * methods must be called before serializing a document.
-     */
-    public abstract Serializer makeSerializer(OutputFormat format);
-
-
-    /**
-     * Create a new serializer, based on the {@link OutputFormat} and
-     * using the writer as the output character stream.  If this
-     * method is used, the encoding property will be ignored.
-     */
-    public abstract Serializer makeSerializer( Writer writer,
-                                               OutputFormat format );
-    
-    
-    /**
-     * Create a new serializer, based on the {@link OutputFormat} and
-     * using the output byte stream and the encoding specified in the
-     * output format.
-     *
-     * @throws UnsupportedEncodingException The specified encoding is
-     *   not supported
-     */
-    public abstract Serializer makeSerializer( OutputStream output,
-                                               OutputFormat format )
-        throws UnsupportedEncodingException;
-    
-
-}
-
-
diff --git a/src/org/apache/xml/serialize/SerializerFactoryImpl.java b/src/org/apache/xml/serialize/SerializerFactoryImpl.java
deleted file mode 100644
index 5a94388..0000000
--- a/src/org/apache/xml/serialize/SerializerFactoryImpl.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xml.serialize;
-
-
-import java.io.OutputStream;
-import java.io.Writer;
-import java.io.UnsupportedEncodingException;
-
-
-/**
- * Default serializer factory can construct serializers for the three
- * markup serializers (XML, HTML, XHTML ).
- *
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:Scott_Boag/CAM/Lotus@lotus.com">Scott Boag</a>
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- */
-final class SerializerFactoryImpl
-    extends SerializerFactory
-{
-
-
-    private String _method;
-    
-    
-    SerializerFactoryImpl( String method )
-    {
-        _method = method;
-        if ( ! _method.equals( Method.XML ) &&
-             ! _method.equals( Method.HTML ) &&
-             ! _method.equals( Method.XHTML ) &&
-             ! _method.equals( Method.TEXT ) )
-            throw new IllegalArgumentException( "SER004 The method '" + method + "' is not supported by this factory\n" + method);
-    }
-
-
-    public Serializer makeSerializer( OutputFormat format )
-    {
-        Serializer serializer;
-        
-        serializer = getSerializer( format );
-        serializer.setOutputFormat( format );
-        return serializer;
-    }
-    
-    
-    
-    public Serializer makeSerializer( Writer writer,
-                                      OutputFormat format )
-    {
-        Serializer serializer;
-        
-        serializer = getSerializer( format );
-        serializer.setOutputCharStream( writer );
-        return serializer;
-    }
-    
-    
-    public Serializer makeSerializer( OutputStream output,
-                                      OutputFormat format )
-        throws UnsupportedEncodingException
-    {
-        Serializer serializer;
-        
-        serializer = getSerializer( format );
-        serializer.setOutputByteStream( output );
-        return serializer;
-    }
-    
-    
-    private Serializer getSerializer( OutputFormat format )
-    {
-        if ( _method.equals( Method.XML ) ) {
-            return new XMLSerializer( format );
-        } else if ( _method.equals( Method.HTML ) ) {
-            return new HTMLSerializer( format );
-        }  else if ( _method.equals( Method.XHTML ) ) {
-            return new XHTMLSerializer( format );
-        }  else if ( _method.equals( Method.TEXT ) ) {
-            return new TextSerializer();
-        } else {
-            throw new IllegalStateException( "SER005 The method '" + _method + "' is not supported by this factory\n" + _method);
-        }
-    }
-    
-    
-    protected String getSupportedMethod()
-    {
-        return _method;
-    }
-
-
-}
-
diff --git a/src/org/apache/xml/serialize/TextSerializer.java b/src/org/apache/xml/serialize/TextSerializer.java
deleted file mode 100755
index 41c4cd9..0000000
--- a/src/org/apache/xml/serialize/TextSerializer.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xml.serialize;
-
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.io.OutputStream;
-import java.io.Writer;
-
-import org.w3c.dom.*;
-import org.xml.sax.DocumentHandler;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.AttributeList;
-import org.xml.sax.Attributes;
-
-
-/**
- * Implements a text serializer supporting both DOM and SAX
- * serializing. For usage instructions see {@link Serializer}.
- * <p>
- * If an output stream is used, the encoding is taken from the
- * output format (defaults to <tt>UTF-8</tt>). If a writer is
- * used, make sure the writer uses the same encoding (if applies)
- * as specified in the output format.
- * <p>
- * The serializer supports both DOM and SAX. DOM serializing is done
- * by calling {@link #serialize} and SAX serializing is done by firing
- * SAX events and using the serializer as a document handler.
- * <p>
- * If an I/O exception occurs while serializing, the serializer
- * will not throw an exception directly, but only throw it
- * at the end of serializing (either DOM or SAX's {@link
- * org.xml.sax.DocumentHandler#endDocument}.
- *
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- * @see Serializer
- */
-public final class TextSerializer
-    extends BaseMarkupSerializer
-{
-
-
-    /**
-     * Constructs a new serializer. The serializer cannot be used without
-     * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
-     * first.
-     */
-    public TextSerializer()
-    {
-        super( new OutputFormat( Method.TEXT, null, false ) );
-    }
-
-
-    public void setOutputFormat( OutputFormat format )
-    {
-        super.setOutputFormat( format != null ? format : new OutputFormat( Method.TEXT, null, false ) );
-    }
-
-
-    //-----------------------------------------//
-    // SAX content handler serializing methods //
-    //-----------------------------------------//
-
-
-    public void startElement( String namespaceURI, String localName,
-                              String rawName, Attributes attrs )
-    {
-        startElement( rawName == null ? localName : rawName, null );
-    }
-
-
-    public void endElement( String namespaceURI, String localName,
-                            String rawName )
-    {
-        endElement( rawName == null ? localName : rawName );
-    }
-
-
-    //------------------------------------------//
-    // SAX document handler serializing methods //
-    //------------------------------000---------//
-
-    
-    public void startElement( String tagName, AttributeList attrs )
-    {
-        boolean      preserveSpace;
-        ElementState state;
-        
-        state = getElementState();
-        if ( isDocumentState() ) {
-            // If this is the root element handle it differently.
-            // If the first root element in the document, serialize
-            // the document's DOCTYPE. Space preserving defaults
-            // to that of the output format.
-            if ( ! _started )
-                startDocument( tagName );
-        }
-        // For any other element, if first in parent, then
-        // use the parnet's space preserving.
-        preserveSpace = state.preserveSpace;
-
-        // Do not change the current element state yet.
-        // This only happens in endElement().
-        
-        // Ignore all other attributes of the element, only printing
-        // its contents.
-        
-        // Now it's time to enter a new element state
-        // with the tag name and space preserving.
-        // We still do not change the curent element state.
-        state = enterElementState( null, null, tagName, preserveSpace );
-    }
-    
-    
-    public void endElement( String tagName )
-    {
-        ElementState state;
-        
-        // Works much like content() with additions for closing
-        // an element. Note the different checks for the closed
-        // element's state and the parent element's state.
-        state = getElementState();
-        // Leave the element state and update that of the parent
-        // (if we're not root) to not empty and after element.
-        state = leaveElementState();
-        state.afterElement = true;
-        state.empty = false;
-        if ( isDocumentState() )
-            _printer.flush();
-    }
-
-
-    public void processingInstruction( String target, String code )
-    {
-    }
-
-
-    public void comment( String text )
-    {
-    }
-
-
-    public void comment( char[] chars, int start, int length )
-    {
-    }
-
-
-    public void characters( char[] chars, int start, int length )
-    {
-        ElementState state;
-        
-        state = content();
-        state.doCData = state.inCData = false;
-        printText( chars, start, length, true, true );
-    }
-
-
-    protected void characters( String text, boolean unescaped )
-    {
-        ElementState state;
-        
-        state = content();
-        state.doCData = state.inCData = false;
-        printText( text, true, true );
-    }
-
-
-    //------------------------------------------//
-    // Generic node serializing methods methods //
-    //------------------------------------------//
-
-
-    /**
-     * Called to serialize the document's DOCTYPE by the root element.
-     * <p>
-     * This method will check if it has not been called before ({@link #_started}),
-     * will serialize the document type declaration, and will serialize all
-     * pre-root comments and PIs that were accumulated in the document
-     * (see {@link #serializePreRoot}). Pre-root will be serialized even if
-     * this is not the first root element of the document.
-     */
-    protected void startDocument( String rootTagName )
-    {
-        // Required to stop processing the DTD, even though the DTD
-        // is not printed.
-        _printer.leaveDTD();
-        
-        _started = true;
-        // Always serialize these, even if not te first root element.
-        serializePreRoot();
-    }
-
-
-    /**
-     * Called to serialize a DOM element. Equivalent to calling {@link
-     * #startElement}, {@link #endElement} and serializing everything
-     * inbetween, but better optimized.
-     */
-    protected void serializeElement( Element elem )
-    {
-        Node         child;
-        ElementState state;
-        boolean      preserveSpace;
-        String       tagName;
-        
-        tagName = elem.getTagName();
-        state = getElementState();
-        if ( isDocumentState() ) {
-            // If this is the root element handle it differently.
-            // If the first root element in the document, serialize
-            // the document's DOCTYPE. Space preserving defaults
-            // to that of the output format.
-            if ( ! _started )
-                startDocument( tagName );
-        }
-        // For any other element, if first in parent, then
-        // use the parnet's space preserving.
-        preserveSpace = state.preserveSpace;
-
-        // Do not change the current element state yet.
-        // This only happens in endElement().
-        
-        // Ignore all other attributes of the element, only printing
-        // its contents.
-        
-        // If element has children, then serialize them, otherwise
-        // serialize en empty tag.
-        if ( elem.hasChildNodes() ) {
-            // Enter an element state, and serialize the children
-            // one by one. Finally, end the element.
-            state = enterElementState( null, null, tagName, preserveSpace );
-            child = elem.getFirstChild();
-            while ( child != null ) {
-                serializeNode( child );
-                child = child.getNextSibling();
-            }
-            endElement( tagName );
-        } else {
-            if ( ! isDocumentState() ) {
-                // After element but parent element is no longer empty.
-                state.afterElement = true;
-                state.empty = false;
-            }
-        }
-    }
-
-
-    /**
-     * Serialize the DOM node. This method is unique to the Text serializer.
-     *
-     * @param node The node to serialize
-     */
-    protected void serializeNode( Node node )
-    {
-        // Based on the node type call the suitable SAX handler.
-        // Only comments entities and documents which are not
-        // handled by SAX are serialized directly.
-        switch ( node.getNodeType() ) {
-        case Node.TEXT_NODE : {
-            String text;
-
-            text = node.getNodeValue();
-            if ( text != null )
-                characters( node.getNodeValue(), true );
-            break;
-        }
-            
-        case Node.CDATA_SECTION_NODE : {
-            String text;
-
-            text = node.getNodeValue();
-            if ( text != null )
-                characters( node.getNodeValue(), true );
-            break;
-        }
-            
-        case Node.COMMENT_NODE :
-            break;
-            
-        case Node.ENTITY_REFERENCE_NODE :
-            // Ignore.
-            break;
-            
-        case Node.PROCESSING_INSTRUCTION_NODE :
-            break;
-            
-        case Node.ELEMENT_NODE :
-            serializeElement( (Element) node );
-            break;
-            
-        case Node.DOCUMENT_NODE :
-            // !!! Fall through
-        case Node.DOCUMENT_FRAGMENT_NODE : {
-            Node         child;
-            
-            // By definition this will happen if the node is a document,
-            // document fragment, etc. Just serialize its contents. It will
-            // work well for other nodes that we do not know how to serialize.
-            child = node.getFirstChild();
-            while ( child != null ) {
-                serializeNode( child );
-                child = child.getNextSibling();
-            }
-            break;
-        }
-        
-        default:
-            break;
-        }
-    }
-    
-    
-    protected ElementState content()
-    {
-        ElementState state;
-        
-        state = getElementState();
-        if ( ! isDocumentState() ) {
-            // If this is the first content in the element,
-            // change the state to not-empty.
-            if ( state.empty )
-                state.empty = false;
-            // Except for one content type, all of them
-            // are not last element. That one content
-            // type will take care of itself.
-            state.afterElement = false;
-        }
-        return state;
-    }
-    
-    
-    protected String getEntityRef( char ch )
-    {
-        return null;
-    }
-
-
-}
-
-
diff --git a/src/org/apache/xml/serialize/XHTMLSerializer.java b/src/org/apache/xml/serialize/XHTMLSerializer.java
deleted file mode 100644
index 3e1faec..0000000
--- a/src/org/apache/xml/serialize/XHTMLSerializer.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-package org.apache.xml.serialize;
-
-
-import java.io.OutputStream;
-import java.io.Writer;
-import java.io.UnsupportedEncodingException;
-
-
-/**
- * Implements an XHTML serializer supporting both DOM and SAX
- * pretty serializing. For usage instructions see either {@link
- * Serializer} or {@link BaseMarkupSerializer}.
- *
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- * @see Serializer
- */
-public final class XHTMLSerializer
-    extends HTMLSerializer
-{
-
-
-    /**
-     * Constructs a new serializer. The serializer cannot be used without
-     * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
-     * first.
-     */
-    public XHTMLSerializer()
-    {
-        super( true, new OutputFormat( Method.XHTML, null, false ) );
-    }
-
-
-    /**
-     * Constructs a new serializer. The serializer cannot be used without
-     * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
-     * first.
-     */
-    public XHTMLSerializer( OutputFormat format )
-    {
-        super( true, format != null ? format : new OutputFormat( Method.XHTML, null, false ) );
-    }
-
-
-    /**
-     * Constructs a new serializer that writes to the specified writer
-     * using the specified output format. If <tt>format</tt> is null,
-     * will use a default output format.
-     *
-     * @param writer The writer to use
-     * @param format The output format to use, null for the default
-     */
-    public XHTMLSerializer( Writer writer, OutputFormat format )
-    {
-        super( true, format != null ? format : new OutputFormat( Method.XHTML, null, false ) );
-        setOutputCharStream( writer );
-    }
-
-
-    /**
-     * Constructs a new serializer that writes to the specified output
-     * stream using the specified output format. If <tt>format</tt>
-     * is null, will use a default output format.
-     *
-     * @param output The output stream to use
-     * @param format The output format to use, null for the default
-     */
-    public XHTMLSerializer( OutputStream output, OutputFormat format )
-    {
-        super( true, format != null ? format : new OutputFormat( Method.XHTML, null, false ) );
-        setOutputByteStream( output );
-    }
-
-
-    public void setOutputFormat( OutputFormat format )
-    {
-        super.setOutputFormat( format != null ? format : new OutputFormat( Method.XHTML, null, false ) );
-    }
-
-
-}
diff --git a/src/org/apache/xml/serialize/XMLSerializer.java b/src/org/apache/xml/serialize/XMLSerializer.java
deleted file mode 100755
index 7f16d55..0000000
--- a/src/org/apache/xml/serialize/XMLSerializer.java
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-
-// Aug 21, 2000:
-//  Fixed bug in startDocument not calling prepare.
-//  Reported by Mikael Staldal <d96-mst-ingen-reklam@d.kth.se>
-// Aug 21, 2000:
-//  Added ability to omit DOCTYPE declaration.
-
-
-package org.apache.xml.serialize;
-
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.io.OutputStream;
-import java.io.Writer;
-import java.util.Enumeration;
-
-import org.w3c.dom.*;
-import org.xml.sax.DocumentHandler;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.AttributeList;
-import org.xml.sax.Attributes;
-
-
-/**
- * Implements an XML serializer supporting both DOM and SAX pretty
- * serializing. For usage instructions see {@link Serializer}.
- * <p>
- * If an output stream is used, the encoding is taken from the
- * output format (defaults to <tt>UTF-8</tt>). If a writer is
- * used, make sure the writer uses the same encoding (if applies)
- * as specified in the output format.
- * <p>
- * The serializer supports both DOM and SAX. DOM serializing is done
- * by calling {@link #serialize} and SAX serializing is done by firing
- * SAX events and using the serializer as a document handler.
- * <p>
- * If an I/O exception occurs while serializing, the serializer
- * will not throw an exception directly, but only throw it
- * at the end of serializing (either DOM or SAX's {@link
- * org.xml.sax.DocumentHandler#endDocument}.
- * <p>
- * For elements that are not specified as whitespace preserving,
- * the serializer will potentially break long text lines at space
- * boundaries, indent lines, and serialize elements on separate
- * lines. Line terminators will be regarded as spaces, and
- * spaces at beginning of line will be stripped.
- *
- *
- * @version $Revision$ $Date$
- * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
- * @see Serializer
- */
-public final class XMLSerializer
-    extends BaseMarkupSerializer
-{
-
-
-    /**
-     * Constructs a new serializer. The serializer cannot be used without
-     * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
-     * first.
-     */
-    public XMLSerializer()
-    {
-        super( new OutputFormat( Method.XML, null, false ) );
-    }
-
-
-    /**
-     * Constructs a new serializer. The serializer cannot be used without
-     * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
-     * first.
-     */
-    public XMLSerializer( OutputFormat format )
-    {
-        super( format != null ? format : new OutputFormat( Method.XML, null, false ) );
-        _format.setMethod( Method.XML );
-    }
-
-
-    /**
-     * Constructs a new serializer that writes to the specified writer
-     * using the specified output format. If <tt>format</tt> is null,
-     * will use a default output format.
-     *
-     * @param writer The writer to use
-     * @param format The output format to use, null for the default
-     */
-    public XMLSerializer( Writer writer, OutputFormat format )
-    {
-        super( format != null ? format : new OutputFormat( Method.XML, null, false ) );
-        _format.setMethod( Method.XML );
-        setOutputCharStream( writer );
-    }
-
-
-    /**
-     * Constructs a new serializer that writes to the specified output
-     * stream using the specified output format. If <tt>format</tt>
-     * is null, will use a default output format.
-     *
-     * @param output The output stream to use
-     * @param format The output format to use, null for the default
-     */
-    public XMLSerializer( OutputStream output, OutputFormat format )
-    {
-        super( format != null ? format : new OutputFormat( Method.XML, null, false ) );
-        _format.setMethod( Method.XML );
-        setOutputByteStream( output );
-    }
-
-
-    public void setOutputFormat( OutputFormat format )
-    {
-        super.setOutputFormat( format != null ? format : new OutputFormat( Method.XML, null, false ) );
-    }
-
-
-    //-----------------------------------------//
-    // SAX content handler serializing methods //
-    //-----------------------------------------//
-
-
-    public void startElement( String namespaceURI, String localName,
-                              String rawName, Attributes attrs )
-    {
-        int          i;
-        boolean      preserveSpace;
-        ElementState state;
-        String       name;
-        String       value;
-        boolean      addNSAttr = false;
-
-        if ( _printer == null )
-            throw new IllegalStateException( "SER002 No writer supplied for serializer" );
-
-        state = getElementState();
-        if ( isDocumentState() ) {
-            // If this is the root element handle it differently.
-            // If the first root element in the document, serialize
-            // the document's DOCTYPE. Space preserving defaults
-            // to that of the output format.
-            if ( ! _started )
-                startDocument( localName == null ? rawName : localName );
-        } else {
-            // For any other element, if first in parent, then
-            // close parent's opening tag and use the parnet's
-            // space preserving.
-            if ( state.empty )
-                _printer.printText( '>' );
-            // Must leave CData section first
-            if ( state.inCData )
-            {
-                _printer.printText( "]]>" );
-                state.inCData = false;
-            }
-            // Indent this element on a new line if the first
-            // content of the parent element or immediately
-            // following an element.
-            if ( _indenting && ! state.preserveSpace &&
-                 ( state.empty || state.afterElement ) )
-                _printer.breakLine();
-        }
-        preserveSpace = state.preserveSpace;
-
-        // Do not change the current element state yet.
-        // This only happens in endElement().
-        if ( rawName == null ) {
-            rawName = localName;
-            if ( namespaceURI != null ) {
-                String prefix;
-                prefix = getPrefix( namespaceURI );
-                if ( prefix.length() > 0 )
-                    rawName = prefix + ":" + localName;
-            }
-            addNSAttr = true;
-        }
-
-        _printer.printText( '<' );
-        _printer.printText( rawName );
-        _printer.indent();
-
-        // For each attribute print it's name and value as one part,
-        // separated with a space so the element can be broken on
-        // multiple lines.
-        if ( attrs != null ) {
-            for ( i = 0 ; i < attrs.getLength() ; ++i ) {
-                _printer.printSpace();
-
-                name = attrs.getQName( i );
-                if ( name == null ) {
-                    String prefix;
-                    String attrURI;
-
-                    name = attrs.getLocalName( i );
-                    attrURI = attrs.getURI( i );
-                    if ( attrURI != null && ( namespaceURI == null ||
-                                              ! attrURI.equals( namespaceURI ) ) ) {
-                        prefix = getPrefix( attrURI );
-                        if ( prefix != null && prefix.length() > 0 )
-                            name = prefix + ":" + name;
-                    }
-                }
-
-                value = attrs.getValue( i );
-                if ( value == null )
-                    value = "";
-                _printer.printText( name );
-                _printer.printText( "=\"" );
-                printEscaped( value );
-                _printer.printText( '"' );
-
-                // If the attribute xml:space exists, determine whether
-                // to preserve spaces in this and child nodes based on
-                // its value.
-                if ( name.equals( "xml:space" ) ) {
-                    if ( value.equals( "preserve" ) )
-                        preserveSpace = true;
-                    else
-                        preserveSpace = _format.getPreserveSpace();
-                }
-            }
-        }
-
-        if ( addNSAttr ) {
-            Enumeration enum;
-
-            enum = _prefixes.keys();
-            while ( enum.hasMoreElements() ) {
-                _printer.printSpace();
-                value = (String) enum.nextElement();
-                name = (String) _prefixes.get( value );
-                if ( name.length() == 0 ) {
-                    _printer.printText( "xmlns=\"" );
-                    printEscaped( value );
-                    _printer.printText( '"' );
-                } else {
-                    _printer.printText( "xmlns:" );
-                    _printer.printText( name );
-                    _printer.printText( "=\"" );
-                    printEscaped( value );
-                    _printer.printText( '"' );
-                }
-            }
-        }
-
-        // Now it's time to enter a new element state
-        // with the tag name and space preserving.
-        // We still do not change the curent element state.
-        state = enterElementState( namespaceURI, localName, rawName, preserveSpace );
-        state.doCData = _format.isCDataElement( namespaceURI == null ? rawName :
-                                                namespaceURI + "^" + localName );
-        state.unescaped = _format.isNonEscapingElement( namespaceURI == null ? rawName :
-                                                        namespaceURI + "^" + localName );
-    }
-
-
-    public void endElement( String namespaceURI, String localName,
-                            String rawName )
-    {
-        ElementState state;
-
-        // Works much like content() with additions for closing
-        // an element. Note the different checks for the closed
-        // element's state and the parent element's state.
-        _printer.unindent();
-        state = getElementState();
-        if ( state.empty ) {
-            _printer.printText( "/>" );
-        } else {
-            // Must leave CData section first
-            if ( state.inCData )
-                _printer.printText( "]]>" );
-            // This element is not empty and that last content was
-            // another element, so print a line break before that
-            // last element and this element's closing tag.
-            if ( _indenting && ! state.preserveSpace && state.afterElement )
-                _printer.breakLine();
-            _printer.printText( "</" );
-            _printer.printText( state.rawName );
-            _printer.printText( '>' );
-        }
-        // Leave the element state and update that of the parent
-        // (if we're not root) to not empty and after element.
-        state = leaveElementState();
-        state.afterElement = true;
-        state.empty = false;
-        if ( isDocumentState() )
-            _printer.flush();
-    }
-
-
-    //------------------------------------------//
-    // SAX document handler serializing methods //
-    //------------------------------------------//
-
-
-    public void startElement( String tagName, AttributeList attrs )
-    {
-        int          i;
-        boolean      preserveSpace;
-        ElementState state;
-        String       name;
-        String       value;
-
-        if ( _printer == null )
-            throw new IllegalStateException( "SER002 No writer supplied for serializer" );
-
-        state = getElementState();
-        if ( isDocumentState() ) {
-            // If this is the root element handle it differently.
-            // If the first root element in the document, serialize
-            // the document's DOCTYPE. Space preserving defaults
-            // to that of the output format.
-            if ( ! _started )
-                startDocument( tagName );
-        } else {
-            // For any other element, if first in parent, then
-            // close parent's opening tag and use the parnet's
-            // space preserving.
-            if ( state.empty )
-                _printer.printText( '>' );
-            // Must leave CData section first
-            if ( state.inCData )
-            {
-                _printer.printText( "]]>" );
-                state.inCData = false;
-            }
-            // Indent this element on a new line if the first
-            // content of the parent element or immediately
-            // following an element.
-            if ( _indenting && ! state.preserveSpace &&
-                 ( state.empty || state.afterElement ) )
-                _printer.breakLine();
-        }
-        preserveSpace = state.preserveSpace;
-
-        // Do not change the current element state yet.
-        // This only happens in endElement().
-
-        _printer.printText( '<' );
-        _printer.printText( tagName );
-        _printer.indent();
-
-        // For each attribute print it's name and value as one part,
-        // separated with a space so the element can be broken on
-        // multiple lines.
-        if ( attrs != null ) {
-            for ( i = 0 ; i < attrs.getLength() ; ++i ) {
-                _printer.printSpace();
-                name = attrs.getName( i );
-                value = attrs.getValue( i );
-                if ( value != null ) {
-                    _printer.printText( name );
-                    _printer.printText( "=\"" );
-                    printEscaped( value );
-                    _printer.printText( '"' );
-                }
-
-                // If the attribute xml:space exists, determine whether
-                // to preserve spaces in this and child nodes based on
-                // its value.
-                if ( name.equals( "xml:space" ) ) {
-                    if ( value.equals( "preserve" ) )
-                        preserveSpace = true;
-                    else
-                        preserveSpace = _format.getPreserveSpace();
-                }
-            }
-        }
-        // Now it's time to enter a new element state
-        // with the tag name and space preserving.
-        // We still do not change the curent element state.
-        state = enterElementState( null, null, tagName, preserveSpace );
-        state.doCData = _format.isCDataElement( tagName );
-        state.unescaped = _format.isNonEscapingElement( tagName );
-    }
-
-
-    public void endElement( String tagName )
-    {
-        endElement( null, null, tagName );
-    }
-
-
-
-    //------------------------------------------//
-    // Generic node serializing methods methods //
-    //------------------------------------------//
-
-
-    /**
-     * Called to serialize the document's DOCTYPE by the root element.
-     * The document type declaration must name the root element,
-     * but the root element is only known when that element is serialized,
-     * and not at the start of the document.
-     * <p>
-     * This method will check if it has not been called before ({@link #_started}),
-     * will serialize the document type declaration, and will serialize all
-     * pre-root comments and PIs that were accumulated in the document
-     * (see {@link #serializePreRoot}). Pre-root will be serialized even if
-     * this is not the first root element of the document.
-     */
-    protected void startDocument( String rootTagName )
-    {
-        int    i;
-        String dtd;
-
-        dtd = _printer.leaveDTD();
-        if ( ! _started ) {
-
-            if ( ! _format.getOmitXMLDeclaration() ) {
-                StringBuffer    buffer;
-
-                // Serialize the document declaration appreaing at the head
-                // of very XML document (unless asked not to).
-                buffer = new StringBuffer( "<?xml version=\"" );
-                if ( _format.getVersion() != null )
-                    buffer.append( _format.getVersion() );
-                else
-                    buffer.append( "1.0" );
-                buffer.append( '"' );
-                if ( _format.getEncoding() != null ) {
-                    buffer.append( " encoding=\"" );
-                    buffer.append( _format.getEncoding() );
-                    buffer.append( '"' );
-                }
-                if ( _format.getStandalone() && _docTypeSystemId == null &&
-                     _docTypePublicId == null )
-                    buffer.append( " standalone=\"yes\"" );
-                buffer.append( "?>" );
-                _printer.printText( buffer );
-                _printer.breakLine();
-            }
-
-            if ( ! _format.getOmitDocumentType() ) {
-                if ( _docTypeSystemId != null ) {
-                    // System identifier must be specified to print DOCTYPE.
-                    // If public identifier is specified print 'PUBLIC
-                    // <public> <system>', if not, print 'SYSTEM <system>'.
-                    _printer.printText( "<!DOCTYPE " );
-                    _printer.printText( rootTagName );
-                    if ( _docTypePublicId != null ) {
-                        _printer.printText( " PUBLIC " );
-                        printDoctypeURL( _docTypePublicId );
-                        if ( _indenting ) {
-                            _printer.breakLine();
-                            for ( i = 0 ; i < 18 + rootTagName.length() ; ++i )
-                                _printer.printText( " " );
-                        } else
-                            _printer.printText( " " );
-                    printDoctypeURL( _docTypeSystemId );
-                    }
-                    else {
-                        _printer.printText( " SYSTEM " );
-                        printDoctypeURL( _docTypeSystemId );
-                    }
-                    
-                    // If we accumulated any DTD contents while printing.
-                    // this would be the place to print it.
-                    if ( dtd != null && dtd.length() > 0 ) {
-                        _printer.printText( " [" );
-                        printText( dtd, true, true );
-                        _printer.printText( ']' );
-                    }
-                    
-                    _printer.printText( ">" );
-                    _printer.breakLine();
-                } else if ( dtd != null && dtd.length() > 0 ) {
-                    _printer.printText( "<!DOCTYPE " );
-                    _printer.printText( rootTagName );
-                    _printer.printText( " [" );
-                    printText( dtd, true, true );
-                    _printer.printText( "]>" );
-                    _printer.breakLine();
-                }
-            }
-        }
-        _started = true;
-        // Always serialize these, even if not te first root element.
-        serializePreRoot();
-    }
-
-
-    /**
-     * Called to serialize a DOM element. Equivalent to calling {@link
-     * #startElement}, {@link #endElement} and serializing everything
-     * inbetween, but better optimized.
-     */
-    protected void serializeElement( Element elem )
-    {
-        Attr         attr;
-        NamedNodeMap attrMap;
-        int          i;
-        Node         child;
-        ElementState state;
-        boolean      preserveSpace;
-        String       name;
-        String       value;
-        String       tagName;
-
-        tagName = elem.getTagName();
-        state = getElementState();
-        if ( isDocumentState() ) {
-            // If this is the root element handle it differently.
-            // If the first root element in the document, serialize
-            // the document's DOCTYPE. Space preserving defaults
-            // to that of the output format.
-            if ( ! _started )
-                startDocument( tagName );
-        } else {
-            // For any other element, if first in parent, then
-            // close parent's opening tag and use the parnet's
-            // space preserving.
-            if ( state.empty )
-                _printer.printText( '>' );
-            // Must leave CData section first
-            if ( state.inCData )
-            {
-                _printer.printText( "]]>" );
-                state.inCData = false;
-            }
-            // Indent this element on a new line if the first
-            // content of the parent element or immediately
-            // following an element.
-            if ( _indenting && ! state.preserveSpace &&
-                 ( state.empty || state.afterElement ) )
-                _printer.breakLine();
-        }
-        preserveSpace = state.preserveSpace;
-
-        // Do not change the current element state yet.
-        // This only happens in endElement().
-
-        _printer.printText( '<' );
-        _printer.printText( tagName );
-        _printer.indent();
-
-        // Lookup the element's attribute, but only print specified
-        // attributes. (Unspecified attributes are derived from the DTD.
-        // For each attribute print it's name and value as one part,
-        // separated with a space so the element can be broken on
-        // multiple lines.
-        attrMap = elem.getAttributes();
-        if ( attrMap != null ) {
-            for ( i = 0 ; i < attrMap.getLength() ; ++i ) {
-                attr = (Attr) attrMap.item( i );
-                name = attr.getName();
-                value = attr.getValue();
-                if ( value == null )
-                    value = "";
-                if ( attr.getSpecified() ) {
-                    _printer.printSpace();
-                    _printer.printText( name );
-                    _printer.printText( "=\"" );
-                    printEscaped( value );
-                    _printer.printText( '"' );
-                }
-                // If the attribute xml:space exists, determine whether
-                // to preserve spaces in this and child nodes based on
-                // its value.
-                if ( name.equals( "xml:space" ) ) {
-                    if ( value.equals( "preserve" ) )
-                        preserveSpace = true;
-                    else
-                        preserveSpace = _format.getPreserveSpace();
-                }
-            }
-        }
-
-        // If element has children, then serialize them, otherwise
-        // serialize en empty tag.
-        if ( elem.hasChildNodes() ) {
-            // Enter an element state, and serialize the children
-            // one by one. Finally, end the element.
-            state = enterElementState( null, null, tagName, preserveSpace );
-            state.doCData = _format.isCDataElement( tagName );
-            state.unescaped = _format.isNonEscapingElement( tagName );
-            child = elem.getFirstChild();
-            while ( child != null ) {
-                serializeNode( child );
-                child = child.getNextSibling();
-            }
-            endElement( tagName );
-        } else {
-            _printer.unindent();
-            _printer.printText( "/>" );
-            // After element but parent element is no longer empty.
-            state.afterElement = true;
-            state.empty = false;
-            if ( isDocumentState() )
-                _printer.flush();
-        }
-    }
-
-
-    protected String getEntityRef( char ch )
-    {
-        // Encode special XML characters into the equivalent character references.
-        // These five are defined by default for all XML documents.
-        switch ( ch ) {
-        case '<':
-            return "lt";
-        case '>':
-            return "gt";
-        case '"':
-            return "quot";
-        case '\'':
-            return "apos";
-        case '&':
-            return "amp";
-        }
-        return null;
-    }
-
-
-}
-
-
diff --git a/src/org/w3c/Makefile b/src/org/w3c/Makefile
deleted file mode 100644
index c2f729e..0000000
--- a/src/org/w3c/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Makefile for directory ./org/w3c
-
-TARGETS=
-
-DIRS = dom
-
-TOP = ../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/w3c/dom/Attr.java b/src/org/w3c/dom/Attr.java
deleted file mode 100644
index f2615d8..0000000
--- a/src/org/w3c/dom/Attr.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  The <code>Attr</code> interface represents an attribute in an 
- * <code>Element</code> object. Typically the allowable values for the 
- * attribute are defined in a document type definition.
- * <p><code>Attr</code> objects inherit the <code>Node</code>  interface, but 
- * since they are not actually child nodes of the element  they describe, the 
- * DOM does not consider them part of the document  tree.  Thus, the 
- * <code>Node</code> attributes <code>parentNode</code> ,  
- * <code>previousSibling</code> , and <code>nextSibling</code> have a  
- * <code>null</code> value for <code>Attr</code> objects. The DOM takes the  
- * view that attributes are properties of elements rather than having a  
- * separate identity from the elements they are associated with;  this should 
- * make it more efficient to implement such features as default attributes 
- * associated with all elements of a  given type.  Furthermore, 
- * <code>Attr</code> nodes may not be immediate children of a 
- * <code>DocumentFragment</code> . However, they can be associated with 
- * <code>Element</code> nodes contained within a <code>DocumentFragment</code>
- *  . In short, users and implementors of the DOM need to be aware that  
- * <code>Attr</code> nodes have some things in  common with other objects 
- * inheriting the <code>Node</code> interface,  but they also are quite 
- * distinct.
- * <p> The attribute's effective value is determined as follows: if this  
- * attribute has been explicitly assigned any value, that value is the  
- * attribute's effective value; otherwise, if there is a declaration for  
- * this attribute, and that declaration includes a default value, then  that 
- * default value is the attribute's effective value; otherwise, the  
- * attribute does not exist on this element in the structure model until  it 
- * has been explicitly added.  Note that the <code>nodeValue</code>  
- * attribute on the <code>Attr</code> instance can also be used to retrieve 
- * the string version of the attribute's value(s). 
- * <p> In XML, where the value of an attribute can contain entity references, 
- * the child nodes of the <code>Attr</code> node provide a representation in 
- * which entity references are not expanded. These child nodes may be either 
- * <code>Text</code> or <code>EntityReference</code> nodes. Because the 
- * attribute type may be unknown, there are no tokenized attribute values. 
- */
-public interface Attr extends Node {
-    /**
-     *  Returns the name of this attribute. 
-     */
-    public String getName();
-
-    /**
-     *  If this attribute was explicitly given a value in the original 
-     * document, this is <code>true</code> ; otherwise, it is 
-     * <code>false</code> . Note that the implementation is in charge of this 
-     * attribute, not the user. If the user changes the value of the 
-     * attribute (even if it ends up having the same value as the default 
-     * value) then the <code>specified</code> flag is automatically flipped 
-     * to <code>true</code> .  To re-specify the attribute as the default 
-     * value from the DTD, the user must delete the attribute. The 
-     * implementation will then make a new attribute available with 
-     * <code>specified</code> set to <code>false</code> and the default value 
-     * (if one exists).
-     * <br> In summary: If the attribute has an assigned value in the document 
-     * then  <code>specified</code> is <code>true</code> , and the value is 
-     * the  assigned value. If the attribute has no assigned value in the 
-     * document and has  a default value in the DTD, then 
-     * <code>specified</code> is <code>false</code> ,  and the value is the 
-     * default value in the DTD. If the attribute has no assigned value in 
-     * the document and has  a value of #IMPLIED in the DTD, then the  
-     * attribute does not appear  in the structure model of the document.
-     */
-    public boolean getSpecified();
-
-    /**
-     *  On retrieval, the value of the attribute is returned as a string. 
-     * Character and general entity references are replaced with their 
-     * values. See also the method <code>getAttribute</code> on the  
-     * <code>Element</code> interface.
-     * <br> On setting, this creates a <code>Text</code> node with the unparsed
-     *  contents of the string. I.e. any characters that an XML processor 
-     * would recognize as markup are instead treated as literal text. See 
-     * also the method <code>setAttribute</code> on the  <code>Element</code> 
-     * interface.
-     * @exception DOMException
-     *    NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
-     */
-    public String getValue();
-    public void setValue(String value)
-                            throws DOMException;
-
-    /**
-     *  The <code>Element</code> node this attribute is attached to or 
-     * <code>null</code> if this attribute is not in use.
-     * @since DOM Level 2
-     */
-    public Element getOwnerElement();
-
-}
-
diff --git a/src/org/w3c/dom/CDATASection.java b/src/org/w3c/dom/CDATASection.java
deleted file mode 100644
index 16edb7e..0000000
--- a/src/org/w3c/dom/CDATASection.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  CDATA sections are used to escape blocks of text containing  characters 
- * that would otherwise be regarded as markup. The only  delimiter that is 
- * recognized in a CDATA section is the "]]&gt;" string  that ends the CDATA 
- * section. CDATA sections cannot be  nested. Their primary purpose is for 
- * including material such as XML fragments, without needing to escape all 
- * the delimiters.
- * <p> The <code>DOMString</code> attribute of the <code>Text</code> node 
- * holds the text that is contained by the CDATA section. Note that this  may 
- * contain characters that need to be escaped outside of CDATA sections and 
- * that, depending on the character encoding ("charset") chosen for 
- * serialization, it may be impossible to write out some characters as part 
- * of a CDATA section. 
- * <p> The <code>CDATASection</code> interface inherits from the 
- * <code>CharacterData</code> interface through the <code>Text</code> 
- * interface. Adjacent <code>CDATASections</code> nodes are not merged by use 
- * of the <code>normalize</code> method of the <code>Element</code> interface.
- *  Because no markup is recognized within a <code>CDATASection</code> , 
- * character numeric references cannot be used as an escape mechanism when 
- * serializing. Therefore, action needs to be taken when serializing a 
- * <code>CDATASection</code> with a character encoding where some of the 
- * contained characters cannot be represented. Failure to do so would not 
- * produce well-formed XML. One potential solution in the serialization 
- * process is to end the CDATA section before the character, output the 
- * character using a  character reference or entity reference, and open a new 
- * CDATA section  for any further characters in the text node. Note, however, 
- * that some  code conversion libraries at the time of writing do not return 
- * an error or exception when a character is missing from the encoding,  
- * making the task of ensuring that data is not corrupted on serialization 
- * more difficult.
- */
-public interface CDATASection extends Text {
-}
-
diff --git a/src/org/w3c/dom/CharacterData.java b/src/org/w3c/dom/CharacterData.java
deleted file mode 100644
index b9bfcdd..0000000
--- a/src/org/w3c/dom/CharacterData.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  The <code>CharacterData</code> interface extends Node with a set of 
- * attributes and methods for accessing character data in the DOM.  For 
- * clarity this set is defined here rather than on each object that uses 
- * these attributes and methods. No DOM objects correspond directly to 
- * <code>CharacterData</code> , though <code>Text</code> and others do 
- * inherit the interface from it. All <code>offsets</code> in this interface 
- * start from 0.
- * <p> As explained in the <code>DOMString</code> interface, text strings in 
- * the DOM are represented in UTF-16, i.e. as a sequence of 16-bit units.  In 
- * the following, the term  16-bit units is used whenever necessary to 
- * indicate that indexing on CharacterData is done in 16-bit units.
- */
-public interface CharacterData extends Node {
-    /**
-     *  The character data of the node that implements this interface. The DOM 
-     * implementation may not put arbitrary limits on the amount of data that 
-     * may be stored in a  <code>CharacterData</code> node. However, 
-     * implementation limits may  mean that the entirety of a node's data may 
-     * not fit into a single <code>DOMString</code> . In such cases, the user 
-     * may call <code>substringData</code> to retrieve the data in 
-     * appropriately sized pieces.
-     * @exception DOMException
-     *    NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
-     * @exception DOMException
-     *    DOMSTRING_SIZE_ERR: Raised when it would return more characters 
-     *   than fit in a <code>DOMString</code> variable on the implementation 
-     *   platform.
-     */
-    public String getData()
-                                  throws DOMException;
-    public void setData(String data)
-                                  throws DOMException;
-
-    /**
-     *  The number of  16-bit units that are available through 
-     * <code>data</code> and the <code>substringData</code> method below.  
-     * This may have the value zero, i.e., <code>CharacterData</code> nodes 
-     * may be empty.
-     */
-    public int getLength();
-
-    /**
-     *  Extracts a range of data from the node.
-     * @param offset  Start offset of substring to extract.
-     * @param count  The number of 16-bit units to extract.
-     * @return  The specified substring. If the sum of <code>offset</code> and 
-     *   <code>count</code> exceeds the <code>length</code> , then all 16-bit 
-     *   units to the end of the data are returned.
-     * @exception DOMException
-     *    INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is 
-     *   negative or greater than the number of 16-bit units in 
-     *   <code>data</code> , or if the specified <code>count</code> is 
-     *   negative.
-     *   <br> DOMSTRING_SIZE_ERR: Raised if the specified range of text does 
-     *   not fit into a <code>DOMString</code> .
-     */
-    public String substringData(int offset, 
-                                int count)
-                                throws DOMException;
-
-    /**
-     *  Append the string to the end of the character data of the node. Upon 
-     * success, <code>data</code> provides access to the concatenation of 
-     * <code>data</code> and the <code>DOMString</code> specified.
-     * @param arg  The <code>DOMString</code> to append.
-     * @exception DOMException
-     *    NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     */
-    public void appendData(String arg)
-                           throws DOMException;
-
-    /**
-     *  Insert a string at the specified character offset.
-     * @param offset  The character offset at which to insert.
-     * @param arg  The <code>DOMString</code> to insert.
-     * @exception DOMException
-     *    INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is 
-     *   negative or greater than the number of 16-bit units in 
-     *   <code>data</code> .
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     */
-    public void insertData(int offset, 
-                           String arg)
-                           throws DOMException;
-
-    /**
-     *  Remove a range of  16-bit units from the node. Upon success, 
-     * <code>data</code> and <code>length</code> reflect the change.
-     * @param offset  The offset from which to start removing.
-     * @param count  The number of 16-bit units to delete. If the sum of 
-     *   <code>offset</code> and <code>count</code> exceeds 
-     *   <code>length</code> then all 16-bit units from <code>offset</code> 
-     *   to the end of the data are deleted.
-     * @exception DOMException
-     *    INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is 
-     *   negative or greater than the number of 16-bit units in 
-     *   <code>data</code> , or if the specified <code>count</code> is 
-     *   negative.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     */
-    public void deleteData(int offset, 
-                           int count)
-                           throws DOMException;
-
-    /**
-     *  Replace the characters starting at the specified  16-bit unit offset 
-     * with the specified string.
-     * @param offset  The offset from which to start replacing.
-     * @param count  The number of 16-bit units to replace. If the sum of 
-     *   <code>offset</code> and <code>count</code> exceeds 
-     *   <code>length</code> , then all 16-bit units to the end of the data 
-     *   are replaced; (i.e., the effect is the same as a <code>remove</code> 
-     *   method call with the same range, followed by an <code>append</code> 
-     *   method invocation).
-     * @param arg  The <code>DOMString</code> with which the range must be 
-     *   replaced.
-     * @exception DOMException
-     *    INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is 
-     *   negative or greater than the number of 16-bit units in 
-     *   <code>data</code> , or if the specified <code>count</code> is 
-     *   negative.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     */
-    public void replaceData(int offset, 
-                            int count, 
-                            String arg)
-                            throws DOMException;
-
-}
-
diff --git a/src/org/w3c/dom/Comment.java b/src/org/w3c/dom/Comment.java
deleted file mode 100644
index 13986f7..0000000
--- a/src/org/w3c/dom/Comment.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  This interface inherits from <code>CharacterData</code> and represents the 
- * content of a comment, i.e., all the characters between the starting '
- * <code>&lt;!--</code> ' and ending '<code>--&gt;</code> '. Note that this 
- * is the definition of a comment in XML, and, in practice, HTML, although 
- * some HTML tools may implement the full SGML comment structure.
- */
-public interface Comment extends CharacterData {
-}
-
diff --git a/src/org/w3c/dom/DOMException.java b/src/org/w3c/dom/DOMException.java
deleted file mode 100644
index 91c29d4..0000000
--- a/src/org/w3c/dom/DOMException.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  DOM operations only raise exceptions in "exceptional" circumstances, 
- * i.e., when an operation is impossible to perform (either for logical 
- * reasons, because data is lost, or  because the implementation has become 
- * unstable). In general, DOM methods return specific error values in ordinary
- *  processing situations, such as out-of-bound errors when using 
- * <code>NodeList</code> .  
- * <p> Implementations may raise other exceptions under other circumstances. 
- * For example, implementations may raise an implementation-dependent  
- * exception if a <code>null</code> argument is passed. 
- * <p> Some languages and object systems do not support the concept of 
- * exceptions. For such systems, error conditions may be indicated using 
- * native error reporting mechanisms. For some bindings, for example, methods 
- * may return error codes similar to those listed in the corresponding method 
- * descriptions.
- */
-public class DOMException extends RuntimeException {
-    public DOMException(short code, String message) {
-       super(message);
-       this.code = code;
-    }
-    public short   code;
-    // ExceptionCode
-    public static final short INDEX_SIZE_ERR            = 1;
-    public static final short DOMSTRING_SIZE_ERR        = 2;
-    public static final short HIERARCHY_REQUEST_ERR     = 3;
-    public static final short WRONG_DOCUMENT_ERR        = 4;
-    public static final short INVALID_CHARACTER_ERR     = 5;
-    public static final short NO_DATA_ALLOWED_ERR       = 6;
-    public static final short NO_MODIFICATION_ALLOWED_ERR = 7;
-    public static final short NOT_FOUND_ERR             = 8;
-    public static final short NOT_SUPPORTED_ERR         = 9;
-    public static final short INUSE_ATTRIBUTE_ERR       = 10;
-    /** 
-     * @since DOM Level 2
-     */ 
-    public static final short INVALID_STATE_ERR         = 11;
-    /** 
-     * @since DOM Level 2
-     */ 
-    public static final short SYNTAX_ERR                = 12;
-    /** 
-     * @since DOM Level 2
-     */ 
-    public static final short INVALID_MODIFICATION_ERR  = 13;
-    /** 
-     * @since DOM Level 2
-     */ 
-    public static final short NAMESPACE_ERR             = 14;
-    /** 
-     * @since DOM Level 2
-     */ 
-    public static final short INVALID_ACCESS_ERR        = 15;
-
-}
-
diff --git a/src/org/w3c/dom/DOMImplementation.java b/src/org/w3c/dom/DOMImplementation.java
deleted file mode 100644
index 93cb472..0000000
--- a/src/org/w3c/dom/DOMImplementation.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  The <code>DOMImplementation</code> interface provides a number of methods 
- * for performing operations that are independent of any particular instance 
- * of the document object model.
- */
-public interface DOMImplementation {
-    /**
-     *  Test if the DOM implementation implements a specific feature.
-     * @param feature  The name of the feature to test (case-insensitive). The 
-     *   legal values are defined throughout this specification and listed in 
-     *   the  section. The name must be an  XML name . To avoid possible 
-     *   conflicts, as a convention, names referring to features defined 
-     *   outside the DOM spec should be made unique by reversing the name of 
-     *   the Internet domain name of the person (or the organization that 
-     *   person belongs to) who defines the feature, component by component, 
-     *   and use this as a prefix. For instance, the W3C SYMM Working Group 
-     *   defines the feature "org.w3c.dom.smil".
-     * @param version  This is the version number of the feature to test. In 
-     *   Level 2, this is the string "2.0". If the version is not specified, 
-     *   supporting any version of the feature causes the method to return 
-     *   <code>true</code> .
-     * @return <code>true</code> if the feature is implemented in the 
-     *   specified version, <code>false</code> otherwise.
-     */
-    public boolean hasFeature(String feature, 
-                              String version);
-
-    /**
-     *  Creates an empty <code>DocumentType</code> node. Entity declarations 
-     * and notations are not made available. Entity reference expansions and 
-     * default attribute additions do not occur. It is expected that a future 
-     * version of the DOM will provide a way for populating a 
-     * <code>DocumentType</code> .
-     * <br> HTML-only DOM implementations do not need to implement this method.
-     * @param qualifiedName  The  qualified name of the document type to be 
-     *   created. 
-     * @param publicId  The external subset public identifier.
-     * @param systemId  The external subset system identifier.
-     * @return  A new <code>DocumentType</code> node with 
-     *   <code>Node.ownerDocument</code> set to <code>null</code> .
-     * @exception DOMException
-     *    INVALID_CHARACTER_ERR: Raised if the specified qualified name 
-     *   contains an illegal character.
-     *   <br> NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is 
-     *   malformed.
-     * @since DOM Level 2
-     */
-    public DocumentType createDocumentType(String qualifiedName, 
-                                           String publicId, 
-                                           String systemId)
-                                           throws DOMException;
-
-    /**
-     *  Creates an XML <code>Document</code> object of the specified type with 
-     * its document element. HTML-only DOM implementations do not need to 
-     * implement this method.
-     * @param namespaceURI  The  namespace URI of the document element to 
-     *   create, or <code>null</code> .
-     * @param qualifiedName  The  qualified name of the document element to be 
-     *   created.
-     * @param doctype  The type of document to be created or <code>null</code> 
-     *   . When <code>doctype</code> is not <code>null</code> , its 
-     *   <code>Node.ownerDocument</code> attribute is set to the document 
-     *   being created.
-     * @return  A new <code>Document</code> object.
-     * @exception DOMException
-     *    INVALID_CHARACTER_ERR: Raised if the specified qualified name 
-     *   contains an illegal character.
-     *   <br> NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is 
-     *   malformed, or if the <code>qualifiedName</code> has a prefix that is 
-     *   "xml" and the <code>namespaceURI</code> is different from 
-     *   "http://www.w3.org/XML/1998/namespace".
-     *   <br> WRONG_DOCUMENT_ERR: Raised if <code>doctype</code> has already 
-     *   been used with a different document.
-     * @since DOM Level 2
-     */
-    public Document createDocument(String namespaceURI, 
-                                   String qualifiedName, 
-                                   DocumentType doctype)
-                                   throws DOMException;
-
-}
-
diff --git a/src/org/w3c/dom/Document.java b/src/org/w3c/dom/Document.java
deleted file mode 100644
index 5a3569d..0000000
--- a/src/org/w3c/dom/Document.java
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  The <code>Document</code> interface represents the entire HTML or XML 
- * document. Conceptually, it is the root of the document tree, and provides 
- * the  primary access to the document's data.
- * <p> Since elements, text nodes, comments, processing instructions, etc. 
- * cannot exist outside the context of a <code>Document</code> , the 
- * <code>Document</code> interface also contains the factory methods needed 
- * to create these objects. The <code>Node</code> objects created have a 
- * <code>ownerDocument</code> attribute which associates them with the 
- * <code>Document</code> within whose context they were created.
- */
-public interface Document extends Node {
-    /**
-     *  The Document Type Declaration (see <code>DocumentType</code> ) 
-     * associated with this document. For HTML documents as well as XML 
-     * documents without a document type declaration this returns 
-     * <code>null</code> . The DOM Level 2 does not support editing the 
-     * Document Type Declaration, therefore <code>docType</code> cannot be 
-     * altered in any way, including through the use of methods, such as 
-     * <code>insertNode</code> or <code>removeNode</code> , inherited from 
-     * <code>Node</code> .
-     */
-    public DocumentType getDoctype();
-
-    /**
-     *  The <code>DOMImplementation</code> object that handles this document. 
-     * A DOM application may use objects from multiple  implementations.
-     */
-    public DOMImplementation getImplementation();
-
-    /**
-     *  This is a convenience attribute that allows direct access to the child 
-     * node that is the root element of  the document. For HTML documents, 
-     * this is the element with the tagName "HTML".
-     */
-    public Element getDocumentElement();
-
-    /**
-     *  Creates an element of the type specified. Note that the instance 
-     * returned implements the <code>Element</code> interface, so attributes 
-     * can be specified directly  on the returned object.
-     * <br> In addition, if there are known attributes with default values, 
-     * <code>Attr</code> nodes representing them are automatically created and
-     *  attached to the element.
-     * <br> To create an element with a qualified name and namespace URI, use 
-     * the <code>createElementNS</code> method.
-     * @param tagName  The name of the element type to instantiate. For XML, 
-     *   this is case-sensitive. For HTML, the  <code>tagName</code> 
-     *   parameter may be provided in any case,  but it must be mapped to the 
-     *   canonical uppercase form by  the DOM implementation. 
-     * @return  A new <code>Element</code> object with the 
-     *   <code>nodeName</code> attribute set to <code>tagName</code> , and 
-     *   <code>localName</code> , <code>prefix</code> , and 
-     *   <code>namespaceURI</code> set to <code>null</code> .
-     * @exception DOMException
-     *    INVALID_CHARACTER_ERR: Raised if the specified name contains an 
-     *   illegal character.
-     */
-    public Element createElement(String tagName)
-                                 throws DOMException;
-
-    /**
-     *  Creates an empty <code>DocumentFragment</code> object. 
-     * @return  A new <code>DocumentFragment</code> .
-     */
-    public DocumentFragment createDocumentFragment();
-
-    /**
-     *  Creates a <code>Text</code> node given the specified string.
-     * @param data  The data for the node.
-     * @return  The new <code>Text</code> object.
-     */
-    public Text createTextNode(String data);
-
-    /**
-     *  Creates a <code>Comment</code> node given the specified string.
-     * @param data  The data for the node.
-     * @return  The new <code>Comment</code> object.
-     */
-    public Comment createComment(String data);
-
-    /**
-     *  Creates a <code>CDATASection</code> node whose value  is the specified 
-     * string.
-     * @param data  The data for the <code>CDATASection</code> contents.
-     * @return  The new <code>CDATASection</code> object.
-     * @exception DOMException
-     *    NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
-     */
-    public CDATASection createCDATASection(String data)
-                                           throws DOMException;
-
-    /**
-     *  Creates a <code>ProcessingInstruction</code> node given the specified 
-     * name and data strings.
-     * @param target  The target part of the processing instruction.
-     * @param data  The data for the node.
-     * @return  The new <code>ProcessingInstruction</code> object.
-     * @exception DOMException
-     *    INVALID_CHARACTER_ERR: Raised if the specified target contains an 
-     *   illegal character.
-     *   <br> NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
-     */
-    public ProcessingInstruction createProcessingInstruction(String target, 
-                                                             String data)
-                                                             throws DOMException;
-
-    /**
-     *  Creates an <code>Attr</code> of the given name. Note that the 
-     * <code>Attr</code> instance can then be set on an <code>Element</code> 
-     * using the <code>setAttribute</code> method. 
-     * <br> To create an attribute with a qualified name and namespace URI, use
-     *  the <code>createAttributeNS</code> method.
-     * @param name  The name of the attribute.
-     * @return  A new <code>Attr</code> object with the <code>nodeName</code> 
-     *   attribute set to <code>name</code> , and <code>localName</code> , 
-     *   <code>prefix</code> , and <code>namespaceURI</code> set to 
-     *   <code>null</code> .
-     * @exception DOMException
-     *    INVALID_CHARACTER_ERR: Raised if the specified name contains an 
-     *   illegal character.
-     */
-    public Attr createAttribute(String name)
-                                throws DOMException;
-
-    /**
-     *  Creates an <code>EntityReference</code> object. In addition, if the 
-     * referenced entity is known, the child list of the 
-     * <code>EntityReference</code> node is made the same as that of the 
-     * corresponding <code>Entity</code> node. If any descendant of the 
-     * <code>Entity</code> node has an unbound  namespace prefix , the 
-     * corresponding descendant of the created <code>EntityReference</code> 
-     * node is also unbound; (its <code>namespaceURI</code> is 
-     * <code>null</code> ). The DOM Level 2 does not support any mechanism to 
-     * resolve namespace prefixes.
-     * @param name  The name of the entity to reference. 
-     * @return  The new <code>EntityReference</code> object.
-     * @exception DOMException
-     *    INVALID_CHARACTER_ERR: Raised if the specified name contains an 
-     *   illegal character.
-     *   <br> NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
-     */
-    public EntityReference createEntityReference(String name)
-                                                 throws DOMException;
-
-    /**
-     *  Returns a <code>NodeList</code> of all the <code>Elements</code> with 
-     * a given tag name in the order in which they would be encountered in a 
-     * preorder traversal of the <code>Document</code> tree. 
-     * @param tagname  The name of the tag to match on. The special value "*" 
-     *   matches all tags.
-     * @return  A new <code>NodeList</code> object containing all the matched 
-     *   <code>Elements</code> .
-     */
-    public NodeList getElementsByTagName(String tagname);
-
-    /**
-     *  Imports a node from another document to this document. The returned 
-     * node has no parent; (<code>parentNode</code> is <code>null</code> ). 
-     * The source node is not altered or removed from the original document; 
-     * this method creates a new copy of the source node.
-     * <br> For all nodes, importing a node creates a node object owned by the 
-     * importing document, with attribute values identical to the source 
-     * node's <code>nodeName</code> and <code>nodeType</code> , plus the 
-     * attributes related to namespaces (<code>prefix</code> , 
-     * <code>localName</code> , and <code>namespaceURI</code> ). As in the 
-     * <code>cloneNode</code> operation on a <code>Node</code> , the source 
-     * node is not altered.
-     * <br> Additional information is copied as appropriate to the 
-     * <code>nodeType</code> , attempting to mirror the behavior expected if a
-     *  fragment of XML or HTML source was copied from one document to 
-     * another, recognizing that the two documents may have different DTDs in 
-     * the XML case. The following list describes the specifics for every 
-     * type of node. 
-     * <dl>
-     * <dt> ELEMENT_NODE</dt>
-     * <dd> Specified attribute nodes of the source 
-     * element are imported, and the generated <code>Attr</code> nodes are 
-     * attached to the generated <code>Element</code> . Default attributes 
-     * are  not copied, though if the document being imported into defines 
-     * default attributes for this element name, those are assigned. If the 
-     * <code>importNode</code> <code>deep</code> parameter was set to 
-     * <code>true</code> , the descendants of the source element will be 
-     * recursively imported and the resulting nodes reassembled to form the 
-     * corresponding subtree.</dd>
-     * <dt> ATTRIBUTE_NODE</dt>
-     * <dd> The <code>specified</code> flag 
-     * is set to <code>true</code> on the generated <code>Attr</code> . The 
-     * descendants of the source <code>Attr</code> are recursively imported 
-     * and the resulting nodes reassembled to form the corresponding subtree. 
-     * Note that the <code>deep</code> parameter does not apply to 
-     * <code>Attr</code> nodes; they always carry their children with them 
-     * when imported.</dd>
-     * <dt> TEXT_NODE, CDATA_SECTION_NODE, COMMENT_NODE</dt>
-     * <dd> These three 
-     * types of nodes inheriting from <code>CharacterData</code> copy their 
-     * <code>data</code> and <code>length</code> attributes from those of the 
-     * source node.</dd>
-     * <dt> ENTITY_REFERENCE_NODE</dt>
-     * <dd> Only the 
-     * <code>EntityReference</code> itself is copied, even if a 
-     * <code>deep</code> import is requested, since the source and 
-     * destination documents might have defined the entity differently. If 
-     * the document being imported into provides a definition for this entity 
-     * name, its value is assigned.</dd>
-     * <dt> ENTITY_NODE</dt>
-     * <dd><code>Entity</code> nodes can 
-     * be imported, however in the current release of the DOM the 
-     * <code>DocumentType</code> is readonly. Ability to add these imported 
-     * nodes to a <code>DocumentType</code> will be considered for addition 
-     * to a future release of the DOM. On import, the <code>publicId</code> , 
-     * <code>systemId</code> , and <code>notationName</code> attributes are 
-     * copied. If a <code>deep</code> import is requested, the descendants of 
-     * the the source <code>Entity</code> is recursively imported and the 
-     * resulting nodes reassembled to form the corresponding subtree.</dd>
-     * <dt> 
-     * PROCESSING_INSTRUCTION_NODE</dt>
-     * <dd> The imported node copies its 
-     * <code>target</code> and <code>data</code> values from those of the 
-     * source node.</dd>
-     * <dt> DOCUMENT_NODE</dt>
-     * <dd><code>Document</code> nodes cannot be 
-     * imported.</dd>
-     * <dt> DOCUMENT_TYPE_NODE</dt>
-     * <dd><code>DocumentType</code> nodes cannot be 
-     * imported.</dd>
-     * <dt> DOCUMENT_FRAGMENT_NODE</dt>
-     * <dd> If the <code>deep</code> option was 
-     * set <code>true</code> , the descendants of the source element will be 
-     * recursively imported and the resulting nodes reassembled to form the 
-     * corresponding subtree. Otherwise, this simply generates an empty 
-     * <code>DocumentFragment</code> .</dd>
-     * <dt> NOTATION_NODE</dt>
-     * <dd><code>Notation</code> 
-     * nodes can be imported, however in the current release of the DOM the 
-     * <code>DocumentType</code> is readonly. Ability to add these imported 
-     * nodes to a <code>DocumentType</code> will be considered for addition 
-     * to a future release of the DOM. On import, the <code>publicId</code> 
-     * and <code>systemId</code> attributes are copied. Note that the 
-     * <code>deep</code> parameter does not apply to <code>Notation</code> 
-     * nodes since they never have any children.</dd>
-     * </dl> 
-     * @param importedNode  The node to import.
-     * @param deep  If <code>true</code> , recursively import the subtree 
-     *   under the specified node; if <code>false</code> , import only the 
-     *   node itself, as explained above. This does not apply to 
-     *   <code>Attr</code> , <code>EntityReference</code> , and 
-     *   <code>Notation</code> nodes.
-     * @return  The imported node that belongs to this <code>Document</code> .
-     * @exception DOMException
-     *    NOT_SUPPORTED_ERR: Raised if the type of node being imported is not 
-     *   supported.
-     * @since DOM Level 2
-     */
-    public Node importNode(Node importedNode, 
-                           boolean deep)
-                           throws DOMException;
-
-    /**
-     *  Creates an element of the given qualified name and namespace URI. 
-     * HTML-only DOM implementations do not need to implement this method.
-     * @param namespaceURI  The  namespace URI of the element to create.
-     * @param qualifiedName  The  qualified name of the element type to 
-     *   instantiate.
-     * @return  A new <code>Element</code> object with the following 
-     *   attributes: Attribute Value<code>Node.nodeName</code>
-     *   <code>qualifiedName</code><code>Node.namespaceURI</code>
-     *   <code>namespaceURI</code><code>Node.prefix</code> prefix, extracted 
-     *   from <code>qualifiedName</code> , or <code>null</code> if there is no
-     *    prefix<code>Node.localName</code> local name , extracted from 
-     *   <code>qualifiedName</code><code>Element.tagName</code>
-     *   <code>qualifiedName</code>
-     * @exception DOMException
-     *    INVALID_CHARACTER_ERR: Raised if the specified qualified name 
-     *   contains an illegal character.
-     *   <br> NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is 
-     *   malformed, if the <code>qualifiedName</code> has a prefix and the 
-     *   <code>namespaceURI</code> is <code>null</code> or an empty string, 
-     *   or if the <code>qualifiedName</code> has a prefix that is "xml" and 
-     *   the <code>namespaceURI</code> is different from 
-     *   "http://www.w3.org/XML/1998/namespace"  .
-     * @since DOM Level 2
-     */
-    public Element createElementNS(String namespaceURI, 
-                                   String qualifiedName)
-                                   throws DOMException;
-
-    /**
-     *  Creates an attribute of the given qualified name and namespace URI. 
-     * HTML-only DOM implementations do not need to implement this method.
-     * @param namespaceURI  The  namespace URI of the attribute to create.
-     * @param qualifiedName  The  qualified name of the attribute to 
-     *   instantiate.
-     * @return  A new <code>Attr</code> object with the following attributes: 
-     *   Attribute Value<code>Node.nodeName</code> qualifiedName
-     *   <code>Node.namespaceURI</code><code>namespaceURI</code>
-     *   <code>Node.prefix</code> prefix, extracted from 
-     *   <code>qualifiedName</code> , or <code>null</code> if there is no 
-     *   prefix<code>Node.localName</code> local name , extracted from 
-     *   <code>qualifiedName</code><code>Attr.name</code>
-     *   <code>qualifiedName</code>
-     * @exception DOMException
-     *    INVALID_CHARACTER_ERR: Raised if the specified qualified name 
-     *   contains an illegal character.
-     *   <br> NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is 
-     *   malformed, if the <code>qualifiedName</code> has a prefix and the 
-     *   <code>namespaceURI</code> is <code>null</code> or an empty string, 
-     *   if the <code>qualifiedName</code> has a prefix that is "xml" and the 
-     *   <code>namespaceURI</code> is different from 
-     *   "http://www.w3.org/XML/1998/namespace", if the 
-     *   <code>qualifiedName</code> has a prefix that is "xmlns" and the 
-     *   <code>namespaceURI</code> is different from 
-     *   "http://www.w3.org/2000/xmlns/", or if the <code>qualifiedName</code>
-     *    is "xmlns" and the <code>namespaceURI</code> is different from 
-     *   "http://www.w3.org/2000/xmlns/".
-     * @since DOM Level 2
-     */
-    public Attr createAttributeNS(String namespaceURI, 
-                                  String qualifiedName)
-                                  throws DOMException;
-
-    /**
-     *  Returns a <code>NodeList</code> of all the <code>Elements</code> with 
-     * a given  local name and namespace URI in the order in which they would 
-     * be encountered in a preorder traversal of the <code>Document</code> 
-     * tree.
-     * @param namespaceURI  The  namespace URI of the elements to match on. 
-     *   The special value "*" matches all namespaces.
-     * @param localName  The  local name of the elements to match on. The 
-     *   special value "*" matches all local names.
-     * @return  A new <code>NodeList</code> object containing all the matched 
-     *   <code>Elements</code> .
-     * @since DOM Level 2
-     */
-    public NodeList getElementsByTagNameNS(String namespaceURI, 
-                                           String localName);
-
-    /**
-     *  Returns the <code>Element</code> whose <code>ID</code> is given by 
-     * <code>elementId</code> . If no such element exists, returns 
-     * <code>null</code> . Behavior is not defined if more than one element 
-     * has this <code>ID</code> .  The DOM implementation must have 
-     * information that says which attributes are of type ID. Attributes with 
-     * the name "ID" are not of type ID unless so defined. Implementations 
-     * that do not know whether attributes are of type ID or not are expected 
-     * to return <code>null</code> .
-     * @param elementId  The unique <code>id</code> value for an element.
-     * @return  The matching element.
-     * @since DOM Level 2
-     */
-    public Element getElementById(String elementId);
-
-}
-
diff --git a/src/org/w3c/dom/DocumentFragment.java b/src/org/w3c/dom/DocumentFragment.java
deleted file mode 100644
index 0a8313f..0000000
--- a/src/org/w3c/dom/DocumentFragment.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- * <code>DocumentFragment</code> is a "lightweight" or "minimal" 
- * <code>Document</code> object. It is very common to want to be able to 
- * extract a portion of a document's tree or to create a new fragment of a 
- * document. Imagine implementing a user command like cut or rearranging a 
- * document by moving fragments around. It is desirable to have an object 
- * which can hold such fragments and it is quite natural to use a Node for 
- * this purpose. While it is true that a <code>Document</code> object could 
- * fulfill this role, a <code>Document</code> object can potentially be a 
- * heavyweight object, depending on the underlying implementation. What is 
- * really needed for this is a very lightweight object. 
- * <code>DocumentFragment</code> is such an object.
- * <p> Furthermore, various operations -- such as inserting nodes as children 
- * of another <code>Node</code> -- may take <code>DocumentFragment</code> 
- * objects as arguments;  this results in all the child nodes of the 
- * <code>DocumentFragment</code> being moved to the child list of this node.
- * <p> The children of a <code>DocumentFragment</code> node are zero or more 
- * nodes representing the tops of any sub-trees defining the structure of the 
- * document. <code>DocumentFragment</code> nodes do not need to be 
- * well-formed XML documents (although they do need to follow the rules 
- * imposed upon well-formed XML parsed entities, which can have multiple top 
- * nodes). For example, a <code>DocumentFragment</code> might have only one 
- * child and that child node could be a <code>Text</code> node. Such a 
- * structure model represents neither an HTML document nor a well-formed XML 
- * document.
- * <p> When a <code>DocumentFragment</code> is inserted into a 
- * <code>Document</code> (or indeed any other <code>Node</code> that may take 
- * children) the children of the <code>DocumentFragment</code> and not the 
- * <code>DocumentFragment</code> itself are inserted into the 
- * <code>Node</code> . This makes the <code>DocumentFragment</code> very 
- * useful when the user wishes to create nodes that are siblings; the 
- * <code>DocumentFragment</code> acts as the parent of these nodes so that 
- * the user can use the standard methods from the <code>Node</code> 
- * interface, such as <code>insertBefore</code> and <code>appendChild</code> .
- */
-public interface DocumentFragment extends Node {
-}
-
diff --git a/src/org/w3c/dom/DocumentType.java b/src/org/w3c/dom/DocumentType.java
deleted file mode 100644
index dbfd7d0..0000000
--- a/src/org/w3c/dom/DocumentType.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  Each <code>Document</code> has a <code>doctype</code> attribute whose 
- * value is either <code>null</code> or a <code>DocumentType</code> object. 
- * The <code>DocumentType</code> interface in the DOM Core provides an 
- * interface to the list of entities that are defined for the document, and 
- * little else because the effect of namespaces and the various XML schema 
- * efforts on DTD representation are not clearly understood as of this 
- * writing.
- * <p> The DOM Level 2 doesn't support editing <code>DocumentType</code> nodes.
- */
-public interface DocumentType extends Node {
-    /**
-     *  The name of DTD; i.e., the name immediately following the 
-     * <code>DOCTYPE</code> keyword.
-     */
-    public String getName();
-
-    /**
-     *  A <code>NamedNodeMap</code> containing the general entities, both 
-     * external and internal, declared in the DTD. Parameter entities are not 
-     *  contained. Duplicates are discarded. For example in:
-     * <pre>
-     * &lt;!DOCTYPE ex SYSTEM "ex.dtd" [
-     *   &lt;!ENTITY foo "foo"&gt;
-     *   &lt;!ENTITY bar "bar"&gt;
-     *   &lt;!ENTITY bar "bar2"&gt;
-     *   &lt;!ENTITY % baz "baz"&gt;
-     * ]&gt;
-     * &lt;ex/&gt;</pre>
-     *   the interface 
-     * provides access to <code>foo</code> and the first declaration of 
-     * <code>bar</code> but not the second declaration of  <code>bar</code> 
-     * or <code>baz</code> . Every node in this map also implements the 
-     * <code>Entity</code> interface.
-     * <br> The DOM Level 2 does not support editing entities, therefore 
-     * <code>entities</code> cannot be altered in any way.
-     */
-    public NamedNodeMap getEntities();
-
-    /**
-     *  A <code>NamedNodeMap</code> containing  the notations declared in the 
-     * DTD. Duplicates are discarded. Every node in this map also implements 
-     * the <code>Notation</code> interface.
-     * <br> The DOM Level 2 does not support editing notations, therefore 
-     * <code>notations</code> cannot be altered in any way.
-     */
-    public NamedNodeMap getNotations();
-
-    /**
-     *  The public identifier of the external subset.
-     * @since DOM Level 2
-     */
-    public String getPublicId();
-
-    /**
-     *  The system identifier of the external subset.
-     * @since DOM Level 2
-     */
-    public String getSystemId();
-
-    /**
-     *  The internal subset as a string.
-     * @since DOM Level 2
-     */
-    public String getInternalSubset();
-
-}
-
diff --git a/src/org/w3c/dom/Element.java b/src/org/w3c/dom/Element.java
deleted file mode 100644
index e79fe0a..0000000
--- a/src/org/w3c/dom/Element.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  The <code>Element</code> interface represents an element in an HTML or XML 
- * document. Elements may have attributes associated with them; since the 
- * <code>Element</code> interface inherits from <code>Node</code> , the 
- * generic <code>Node</code> interface attribute <code>attributes</code> may 
- * be used to retrieve the set of all attributes for an element. There are 
- * methods on the <code>Element</code> interface to retrieve either an 
- * <code>Attr</code> object by name or an attribute value by name. In XML, 
- * where an attribute value may contain entity references, an 
- * <code>Attr</code> object should be retrieved to examine the possibly 
- * fairly complex sub-tree representing the attribute value. On the other 
- * hand, in HTML, where all attributes have simple string values, methods to 
- * directly access an attribute value can safely be used as a convenience. In 
- * DOM Level 2, the method <code>normalize</code> is inherited from the 
- * <code>Node</code> interface where it was moved.
- */
-public interface Element extends Node {
-    /**
-     *  The name of the element. For example, in: 
-     * <pre>
-     * &lt;elementExample id="demo"&gt; 
-     *         ... 
-     * &lt;/elementExample&gt; ,</pre>
-     *  <code>tagName</code> has 
-     * the value <code>"elementExample"</code> . Note that this is 
-     * case-preserving in XML, as are all of the operations of the DOM. The 
-     * HTML DOM returns the <code>tagName</code> of an HTML element in the 
-     * canonical uppercase form, regardless of the case in the  source HTML 
-     * document. 
-     */
-    public String getTagName();
-
-    /**
-     *  Retrieves an attribute value by name.
-     * @param name  The name of the attribute to retrieve.
-     * @return  The <code>Attr</code> value as a string, or the empty string if
-     *    that attribute does not have a specified or default value.
-     */
-    public String getAttribute(String name);
-
-    /**
-     *  Adds a new attribute. If an attribute with that name is already 
-     * present in the element, its value is changed to be that of the value 
-     * parameter. This value is a simple string; it is not parsed as it is 
-     * being set. So any markup (such as syntax to be recognized as an entity 
-     * reference) is treated as literal text, and needs to be appropriately 
-     * escaped by the implementation when it is written out. In order to 
-     * assign an attribute value that contains entity references, the user 
-     * must create an <code>Attr</code> node plus any <code>Text</code> and 
-     * <code>EntityReference</code> nodes, build the appropriate subtree, and 
-     * use <code>setAttributeNode</code> to assign it as the value of an 
-     * attribute.
-     * <br> To set an attribute with a qualified name and namespace URI, use 
-     * the <code>setAttributeNS</code> method.
-     * @param name  The name of the attribute to create or alter.
-     * @param value  Value to set in string form.
-     * @exception DOMException
-     *    INVALID_CHARACTER_ERR: Raised if the specified name contains an 
-     *   illegal character.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     */
-    public void setAttribute(String name, 
-                             String value)
-                             throws DOMException;
-
-    /**
-     *  Removes an attribute by name. If the removed attribute is known to 
-     * have a default value, an attribute immediately appears containing the 
-     * default value as well as the corresponding namespace URI, local name, 
-     * and prefix when applicable.
-     * <br> To remove an attribute by local name and namespace URI, use the 
-     * <code>removeAttributeNS</code> method.
-     * @param name  The name of the attribute to remove.
-     * @exception DOMException
-     *    NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     */
-    public void removeAttribute(String name)
-                                throws DOMException;
-
-    /**
-     *  Retrieves an attribute node by name.
-     * <br> To retrieve an attribute node by qualified name and namespace URI, 
-     * use the <code>getAttributeNodeNS</code> method.
-     * @param name  The name (<code>nodeName</code> ) of the attribute to 
-     *   retrieve.
-     * @return  The <code>Attr</code> node with the specified name (
-     *   <code>nodeName</code> ) or <code>null</code> if there is no such 
-     *   attribute.
-     */
-    public Attr getAttributeNode(String name);
-
-    /**
-     *  Adds a new attribute node. If an attribute with that name (
-     * <code>nodeName</code> ) is already present in the element, it is 
-     * replaced by the new one.
-     * <br> To add a new attribute node with a qualified name and namespace 
-     * URI, use the <code>setAttributeNodeNS</code> method.
-     * @param newAttr  The <code>Attr</code> node to add to the attribute list.
-     * @return  If the <code>newAttr</code> attribute replaces an existing 
-     *   attribute, the replaced <code>Attr</code> node is returned, 
-     *   otherwise <code>null</code> is returned.
-     * @exception DOMException
-     *    WRONG_DOCUMENT_ERR: Raised if <code>newAttr</code> was created from 
-     *   a different document than the one that created the element.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     *   <br> INUSE_ATTRIBUTE_ERR: Raised if <code>newAttr</code> is already 
-     *   an attribute of another <code>Element</code> object. The DOM user 
-     *   must explicitly clone <code>Attr</code> nodes to re-use them in 
-     *   other elements.
-     */
-    public Attr setAttributeNode(Attr newAttr)
-                                 throws DOMException;
-
-    /**
-     *  Removes the specified attribute node. If the removed <code>Attr</code> 
-     * has a default value it is immediately replaced. The replacing 
-     * attribute has the same namespace URI and local name, as well as the 
-     * original prefix, when applicable.
-     * @param oldAttr  The <code>Attr</code> node to remove from the attribute 
-     *   list.
-     * @return  The <code>Attr</code> node that was removed.
-     * @exception DOMException
-     *    NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     *   <br> NOT_FOUND_ERR: Raised if <code>oldAttr</code> is not an 
-     *   attribute of the element.
-     */
-    public Attr removeAttributeNode(Attr oldAttr)
-                                    throws DOMException;
-
-    /**
-     *  Returns a <code>NodeList</code> of all descendant elements with a 
-     * given tag name, in the order in which they would be encountered in a 
-     * preorder traversal of the <code>Element</code> tree.
-     * @param name  The name of the tag to match on. The special value "*" 
-     *   matches all tags.
-     * @return  A list of matching <code>Element</code> nodes.
-     */
-    public NodeList getElementsByTagName(String name);
-
-    /**
-     *  Retrieves an attribute value by local name and namespace URI. 
-     * HTML-only DOM implementations do not need to implement this method.
-     * @param namespaceURI  The  namespace URI of the attribute to retrieve.
-     * @param localName  The  local name of the attribute to retrieve.
-     * @return  The <code>Attr</code> value as a string, or an 
-     *   <code>null</code> if that attribute does not have a specified or 
-     *   default value.  This is different from <code>getAttribute</code> 
-     *   which never return <code>null</code> . 
-     * @since DOM Level 2
-     */
-    public String getAttributeNS(String namespaceURI, 
-                                 String localName);
-
-    /**
-     *  Adds a new attribute. If an attribute with the same local name and 
-     * namespace URI is already present on the element, its prefix is changed 
-     * to be the prefix part of the <code>qualifiedName</code> , and its 
-     * value is changed to be the <code>value</code> parameter. This value is 
-     * a simple string; it is not parsed as it is being set. So any markup 
-     * (such as syntax to be recognized as an entity reference) is treated as 
-     * literal text, and needs to be appropriately escaped by the 
-     * implementation when it is written out. In order to assign an attribute 
-     * value that contains entity references, the user must create an 
-     * <code>Attr</code> node plus any <code>Text</code> and 
-     * <code>EntityReference</code> nodes, build the appropriate subtree, and 
-     * use <code>setAttributeNodeNS</code> or <code>setAttributeNode</code> to
-     *  assign it as the value of an attribute.
-     * <br> HTML-only DOM implementations do not need to implement this method.
-     * @param namespaceURI  The  namespace URI of the attribute to create or 
-     *   alter.
-     * @param qualifiedName  The  qualified name of the attribute to create or 
-     *   alter.
-     * @param value  The value to set in string form.
-     * @exception DOMException
-     *    INVALID_CHARACTER_ERR: Raised if the specified qualified name 
-     *   contains an illegal character.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     *   <br> NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is 
-     *   malformed, if the <code>qualifiedName</code> has a prefix and the 
-     *   <code>namespaceURI</code> is <code>null</code> or an empty string, 
-     *   if the <code>qualifiedName</code> has a prefix that is "xml" and the 
-     *   <code>namespaceURI</code> is different from 
-     *   "http://www.w3.org/XML/1998/namespace", if the 
-     *   <code>qualifiedName</code> has a prefix that is "xmlns" and the 
-     *   <code>namespaceURI</code> is different from 
-     *   "http://www.w3.org/2000/xmlns/", or if the <code>qualifiedName</code>
-     *    is "xmlns" and the <code>namespaceURI</code> is different from 
-     *   "http://www.w3.org/2000/xmlns/".
-     * @since DOM Level 2
-     */
-    public void setAttributeNS(String namespaceURI, 
-                               String qualifiedName, 
-                               String value)
-                               throws DOMException;
-
-    /**
-     *  Removes an attribute by local name and namespace URI. If the removed 
-     * attribute has a default value it is immediately replaced. The 
-     * replacing attribute has the same namespace URI and local name, as well 
-     * as the original prefix.
-     * <br> HTML-only DOM implementations do not need to implement this method.
-     * @param namespaceURI  The  namespace URI of the attribute to remove.
-     * @param localName  The  local name of the attribute to remove.
-     * @exception DOMException
-     *    NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     * @since DOM Level 2
-     */
-    public void removeAttributeNS(String namespaceURI, 
-                                  String localName)
-                                  throws DOMException;
-
-    /**
-     *  Retrieves an <code>Attr</code> node by local name and namespace URI. 
-     * HTML-only DOM implementations do not need to implement this method.
-     * @param namespaceURI  The  namespace URI of the attribute to retrieve.
-     * @param localName  The  local name of the attribute to retrieve.
-     * @return  The <code>Attr</code> node with the specified attribute local 
-     *   name and namespace URI or <code>null</code> if there is no such 
-     *   attribute.
-     * @since DOM Level 2
-     */
-    public Attr getAttributeNodeNS(String namespaceURI, 
-                                   String localName);
-
-    /**
-     *  Adds a new attribute. If an attribute with that local name and that 
-     * namespace URI is already present in the element, it is replaced by the 
-     * new one.
-     * <br> HTML-only DOM implementations do not need to implement this method.
-     * @param newAttr  The <code>Attr</code> node to add to the attribute list.
-     * @return  If the <code>newAttr</code> attribute replaces an existing 
-     *   attribute with the same  local name and  namespace URI , the 
-     *   replaced <code>Attr</code> node is returned, otherwise 
-     *   <code>null</code> is returned.
-     * @exception DOMException
-     *    WRONG_DOCUMENT_ERR: Raised if <code>newAttr</code> was created from 
-     *   a different document than the one that created the element.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     *   <br> INUSE_ATTRIBUTE_ERR: Raised if <code>newAttr</code> is already 
-     *   an attribute of another <code>Element</code> object. The DOM user 
-     *   must explicitly clone <code>Attr</code> nodes to re-use them in 
-     *   other elements.
-     * @since DOM Level 2
-     */
-    public Attr setAttributeNodeNS(Attr newAttr)
-                                   throws DOMException;
-
-    /**
-     *  Returns a <code>NodeList</code> of all the <code>Elements</code> with 
-     * a given local name and namespace URI in the order in which they would 
-     * be encountered in a preorder traversal of the <code>Document</code> 
-     * tree, starting from this node.
-     * <br> HTML-only DOM implementations do not need to implement this method.
-     * @param namespaceURI  The  namespace URI of the elements to match on. 
-     *   The special value "*" matches all namespaces.
-     * @param localName  The  local name of the elements to match on. The 
-     *   special value "*" matches all local names.
-     * @return  A new <code>NodeList</code> object containing all the matched 
-     *   <code>Elements</code> .
-     * @since DOM Level 2
-     */
-    public NodeList getElementsByTagNameNS(String namespaceURI, 
-                                           String localName);
-
-    /**
-     *  Returns <code>true</code> when an attribute with a given name is 
-     * specified on this element or has a default value, <code>false</code> 
-     * otherwise.
-     * @param name  The name of the attribute to look for.
-     * @return <code>true</code> if an attribute with the given name is 
-     *   specified on this element or has a default value, <code>false</code> 
-     *   otherwise.
-     * @since DOM Level 2
-     */
-    public boolean hasAttribute(String name);
-
-    /**
-     *  Returns <code>true</code> when an attribute with a given local name 
-     * and namespace URI is specified on this element or has a default value, 
-     * <code>false</code> otherwise. HTML-only DOM implementations do not 
-     * need to implement this method.
-     * @param namespaceURI  The  namespace URI of the attribute to look for.
-     * @param localName  The  local name of the attribute to look for.
-     * @return <code>true</code> if an attribute with the given local name and 
-     *   namespace URI is specified or has a default value on this element, 
-     *   <code>false</code> otherwise.
-     * @since DOM Level 2
-     */
-    public boolean hasAttributeNS(String namespaceURI, 
-                                  String localName);
-
-}
-
diff --git a/src/org/w3c/dom/Entity.java b/src/org/w3c/dom/Entity.java
deleted file mode 100644
index c6f5236..0000000
--- a/src/org/w3c/dom/Entity.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  This interface represents an entity, either parsed or unparsed, in an XML 
- * document. Note that this models the entity itself  not the entity 
- * declaration. <code>Entity</code> declaration modeling has been left for a 
- * later Level of the DOM specification.
- * <p> The <code>nodeName</code> attribute that is inherited from 
- * <code>Node</code> contains the name of the entity.
- * <p> An XML processor may choose to completely expand entities before  the 
- * structure model is passed to the DOM; in this case there will be no 
- * <code>EntityReference</code> nodes in the document tree.
- * <p> XML does not mandate that a non-validating XML processor read and 
- * process entity declarations made in the external subset or declared in 
- * external parameter entities. This means that parsed entities declared in 
- * the external subset need not be expanded by some classes of applications, 
- * and that the replacement value of the entity may not be available. When the
- *  replacement value is available, the corresponding  <code>Entity</code> 
- * node's child list represents the structure of that replacement text. 
- * Otherwise, the child list is empty.
- * <p> The DOM Level 2 does not support editing <code>Entity</code> nodes; if 
- * a user wants to make changes to the contents of an <code>Entity</code> , 
- * every related <code>EntityReference</code> node has to be replaced in the 
- * structure model by a clone of the <code>Entity</code> 's contents, and 
- * then the desired changes must be made to each of those clones instead. All 
- * the descendants of an <code>Entity</code> node are readonly.
- * <p> An <code>Entity</code> node does not have any parent. If the entity 
- * contains an unbound  namespace prefix , the <code>namespaceURI</code> of 
- * the corresponding node in the <code>Entity</code> node subtree is 
- * <code>null</code> . The same is true for <code>EntityReference</code> 
- * nodes that refer to this entity, when they are created using the 
- * <code>createEntityReference</code> method of the <code>Document</code> 
- * interface. The DOM Level 2 does not support any mechanism to resolve 
- * namespace prefixes.
- */
-public interface Entity extends Node {
-    /**
-     *  The public identifier associated with the entity, if specified. If the 
-     * public identifier was not specified, this is <code>null</code> .
-     */
-    public String getPublicId();
-
-    /**
-     *  The system identifier associated with the entity, if specified. If the 
-     * system identifier was not specified, this is <code>null</code> .
-     */
-    public String getSystemId();
-
-    /**
-     *  For unparsed entities, the name of the notation for the entity. For 
-     * parsed entities, this is <code>null</code> . 
-     */
-    public String getNotationName();
-
-}
-
diff --git a/src/org/w3c/dom/EntityReference.java b/src/org/w3c/dom/EntityReference.java
deleted file mode 100644
index ce49129..0000000
--- a/src/org/w3c/dom/EntityReference.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- * <code>EntityReference</code> objects may be inserted into the structure 
- * model when an entity reference is in the source document, or when the user 
- * wishes to insert an entity reference. Note that character references and 
- * references to predefined entities are considered to be expanded by the 
- * HTML or XML processor so that characters are represented by their Unicode 
- * equivalent rather than by an entity reference. Moreover, the XML processor 
- * may completely expand references to entities while building the structure 
- * model, instead of providing <code>EntityReference</code> objects. If it 
- * does provide such objects, then for a given <code>EntityReference</code> 
- * node, it may be that there is no <code>Entity</code> node representing the 
- * referenced entity. If such an <code>Entity</code> exists, then the child 
- * list of the <code>EntityReference</code> node is in general the same as 
- * that of the <code>Entity</code> node. They may differ when an entity 
- * contains an unbound  namespace prefix . In such a case, because the 
- * namespace prefix resolution depends on where the entity reference is, the 
- * descendants of the <code>EntityReference</code> node may be bound to 
- * different  namespace URIs .
- * <p> As with the <code>Entity</code> node, all descendants of the 
- * <code>EntityReference</code> are readonly.
- */
-public interface EntityReference extends Node {
-}
-
diff --git a/src/org/w3c/dom/Makefile b/src/org/w3c/dom/Makefile
deleted file mode 100644
index 44b0cf3..0000000
--- a/src/org/w3c/dom/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-# Makefile for directory ./org/w3c/dom
-
-TARGETS=\
-	Attr.class\
-	CDATASection.class\
-	CharacterData.class\
-	Comment.class\
-	Document.class\
-	DocumentFragment.class\
-	DocumentType.class\
-	DOMException.class\
-	DOMImplementation.class\
-	Element.class\
-	Entity.class\
-	EntityReference.class\
-	NamedNodeMap.class\
-	Node.class\
-	NodeList.class\
-	Notation.class\
-	ProcessingInstruction.class\
-	Text.class
-
-DIRS = events html traversal range
-
-TOP = ../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/w3c/dom/NamedNodeMap.java b/src/org/w3c/dom/NamedNodeMap.java
deleted file mode 100644
index 889f3e2..0000000
--- a/src/org/w3c/dom/NamedNodeMap.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  Objects implementing the <code>NamedNodeMap</code> interface are used to 
- * represent collections of nodes that can be accessed by name. Note that 
- * <code>NamedNodeMap</code> does not inherit from <code>NodeList</code> ; 
- * <code>NamedNodeMaps</code> are not maintained in any particular order. 
- * Objects contained in an object implementing <code>NamedNodeMap</code> may 
- * also be accessed by an ordinal index, but this is simply to allow 
- * convenient enumeration of the contents of a <code>NamedNodeMap</code> , 
- * and does not imply that the DOM specifies an order to these Nodes. 
- */
-public interface NamedNodeMap {
-    /**
-     *  Retrieves a node specified by name.
-     * @param name  The <code>nodeName</code> of a node to retrieve.
-     * @return  A <code>Node</code> (of any type) with the specified 
-     *   <code>nodeName</code> , or <code>null</code> if it does not identify 
-     *   any node in this map.
-     */
-    public Node getNamedItem(String name);
-
-    /**
-     *  Adds a node using its <code>nodeName</code> attribute. If a node with 
-     * that name is already present in this map, it is replaced by the new 
-     * one.
-     * <br> As the <code>nodeName</code> attribute is used to derive the name 
-     * which the node must be stored under, multiple nodes of certain types 
-     * (those that have a "special" string value) cannot be stored as the 
-     * names would clash. This is seen as preferable to allowing nodes to be 
-     * aliased.
-     * @param arg  A node to store in this map. The node will later be 
-     *   accessible using the value of its <code>nodeName</code> attribute.
-     * @return  If the new <code>Node</code> replaces an existing node the 
-     *   replaced <code>Node</code> is returned, otherwise <code>null</code> 
-     *   is returned.
-     * @exception DOMException
-     *    WRONG_DOCUMENT_ERR: Raised if <code>arg</code> was created from a 
-     *   different document than the one that created this map.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
-     *   <br> INUSE_ATTRIBUTE_ERR: Raised if <code>arg</code> is an 
-     *   <code>Attr</code> that is already an attribute of another 
-     *   <code>Element</code> object. The DOM user must explicitly clone 
-     *   <code>Attr</code> nodes to re-use them in other elements.
-     */
-    public Node setNamedItem(Node arg)
-                             throws DOMException;
-
-    /**
-     *  Removes a node specified by name. A removed attribute may be known to 
-     * have a default value when this map contains the attributes attached to 
-     * an element, as returned by the attributes attribute of the 
-     * <code>Node</code> interface. If so, an attribute immediately appears 
-     * containing the default value as well as the corresponding namespace 
-     * URI, local name, and prefix when applicable.
-     * @param name  The <code>nodeName</code> of the node to remove.
-     * @return  The node removed from this map if a node with such a name 
-     *   exists.
-     * @exception DOMException
-     *    NOT_FOUND_ERR: Raised if there is no node named <code>name</code> 
-     *   in this map.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
-     */
-    public Node removeNamedItem(String name)
-                                throws DOMException;
-
-    /**
-     *  Returns the <code>index</code> th item in the map. If 
-     * <code>index</code> is greater than or equal to the number of nodes in 
-     * this map, this returns <code>null</code> .
-     * @param index  Index into this map.
-     * @return  The node at the <code>index</code> th position in the map, or 
-     *   <code>null</code> if that is not a valid index.
-     */
-    public Node item(int index);
-
-    /**
-     *  The number of nodes in this map. The range of valid child node indices 
-     * is <code>0</code> to <code>length-1</code> inclusive. 
-     */
-    public int getLength();
-
-    /**
-     *  Retrieves a node specified by local name and namespace URI. HTML-only 
-     * DOM implementations do not need to implement this method.
-     * @param namespaceURI  The  namespace URI of the node to retrieve.
-     * @param localName  The  local name of the node to retrieve.
-     * @return  A <code>Node</code> (of any type) with the specified local 
-     *   name and namespace URI, or <code>null</code> if they do not identify 
-     *   any node in this map.
-     * @since DOM Level 2
-     */
-    public Node getNamedItemNS(String namespaceURI, 
-                               String localName);
-
-    /**
-     *  Adds a node using its <code>namespaceURI</code> and 
-     * <code>localName</code> . If a node with that namespace URI and that 
-     * local name is already present in this map, it is replaced by the new 
-     * one.
-     * <br> HTML-only DOM implementations do not need to implement this method.
-     * @param arg  A node to store in this map. The node will later be 
-     *   accessible using the value of its <code>namespaceURI</code> and 
-     *   <code>localName</code> attributes.
-     * @return  If the new <code>Node</code> replaces an existing node the 
-     *   replaced <code>Node</code> is returned, otherwise <code>null</code> 
-     *   is returned.
-     * @exception DOMException
-     *    WRONG_DOCUMENT_ERR: Raised if <code>arg</code> was created from a 
-     *   different document than the one that created this map.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
-     *   <br> INUSE_ATTRIBUTE_ERR: Raised if <code>arg</code> is an 
-     *   <code>Attr</code> that is already an attribute of another 
-     *   <code>Element</code> object. The DOM user must explicitly clone 
-     *   <code>Attr</code> nodes to re-use them in other elements.
-     * @since DOM Level 2
-     */
-    public Node setNamedItemNS(Node arg)
-                               throws DOMException;
-
-    /**
-     *  Removes a node specified by local name and namespace URI. A removed 
-     * attribute may be known to have a default value when this map contains 
-     * the attributes attached to an element, as returned by the attributes 
-     * attribute of the <code>Node</code> interface. If so, an attribute 
-     * immediately appears containing the default value as well as the 
-     * corresponding namespace URI, local name, and prefix when applicable.
-     * <br> HTML-only DOM implementations do not need to implement this method.
-     * @param namespaceURI  The  namespace URI of the node to remove.
-     * @param localName  The  local name of the node to remove.
-     * @return  The node removed from this map if a node with such a local 
-     *   name and namespace URI exists.
-     * @exception DOMException
-     *    NOT_FOUND_ERR: Raised if there is no node with the specified 
-     *   <code>namespaceURI</code> and <code>localName</code> in this map.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
-     * @since DOM Level 2
-     */
-    public Node removeNamedItemNS(String namespaceURI, 
-                                  String localName)
-                                  throws DOMException;
-
-}
-
diff --git a/src/org/w3c/dom/Node.java b/src/org/w3c/dom/Node.java
deleted file mode 100644
index f916f6b..0000000
--- a/src/org/w3c/dom/Node.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  The <code>Node</code> interface is the primary datatype for the entire 
- * Document Object Model. It represents a single node in the document tree. 
- * While all objects implementing the <code>Node</code> interface expose 
- * methods for dealing with children, not all objects implementing the 
- * <code>Node</code> interface may have children. For example, 
- * <code>Text</code> nodes may not have children, and adding children to such 
- * nodes results in a <code>DOMException</code> being raised.
- * <p> The attributes <code>nodeName</code> , <code>nodeValue</code> and 
- * <code>attributes</code> are included as a mechanism to get at node 
- * information without casting down to the specific derived interface. In 
- * cases where there is no obvious mapping of these attributes for a specific 
- * <code>nodeType</code> (e.g., <code>nodeValue</code> for an 
- * <code>Element</code> or <code>attributes</code> for a <code>Comment</code> 
- * ), this returns <code>null</code> . Note that the specialized interfaces 
- * may contain additional and more convenient mechanisms to get and set the 
- * relevant information.
- */
-public interface Node {
-    // NodeType
-    public static final short ELEMENT_NODE              = 1;
-    public static final short ATTRIBUTE_NODE            = 2;
-    public static final short TEXT_NODE                 = 3;
-    public static final short CDATA_SECTION_NODE        = 4;
-    public static final short ENTITY_REFERENCE_NODE     = 5;
-    public static final short ENTITY_NODE               = 6;
-    public static final short PROCESSING_INSTRUCTION_NODE = 7;
-    public static final short COMMENT_NODE              = 8;
-    public static final short DOCUMENT_NODE             = 9;
-    public static final short DOCUMENT_TYPE_NODE        = 10;
-    public static final short DOCUMENT_FRAGMENT_NODE    = 11;
-    public static final short NOTATION_NODE             = 12;
-
-    /**
-     *  The name of this node, depending on its type; see the table above. 
-     */
-    public String getNodeName();
-
-    /**
-     *  The value of this node, depending on its type; see the table above. 
-     * When it is defined to be <code>null</code> , setting it has no effect.
-     * @exception DOMException
-     *    NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
-     * @exception DOMException
-     *    DOMSTRING_SIZE_ERR: Raised when it would return more characters 
-     *   than fit in a <code>DOMString</code> variable on the implementation 
-     *   platform.
-     */
-    public String getNodeValue()
-                                  throws DOMException;
-    public void setNodeValue(String nodeValue)
-                                  throws DOMException;
-
-    /**
-     *  A code representing the type of the underlying object, as defined 
-     * above.
-     */
-    public short getNodeType();
-
-    /**
-     *  The parent of this node. All nodes, except <code>Attr</code> , 
-     * <code>Document</code> , <code>DocumentFragment</code> , 
-     * <code>Entity</code> , and <code>Notation</code> may have a parent. 
-     * However, if a	node has just been created and not yet added to the 
-     * tree, or if it has been removed from the tree, this is 
-     * <code>null</code> .
-     */
-    public Node getParentNode();
-
-    /**
-     *  A <code>NodeList</code> that contains all children of this node. If 
-     * there are no children, this is a <code>NodeList</code> containing no 
-     * nodes. The content of the returned <code>NodeList</code> is "live" in 
-     * the sense that, for instance, changes to the children of the node 
-     * object that it	was created from are immediately reflected in the nodes 
-     * returned by the <code>NodeList</code> accessors; it is not a static 
-     * snapshot of the content of the node. This is true for every 
-     * <code>NodeList</code> , including the ones returned by the 
-     * <code>getElementsByTagName</code> method.
-     */
-    public NodeList getChildNodes();
-
-    /**
-     *  The first child of this node. If there is no such node, this returns 
-     * <code>null</code> .
-     */
-    public Node getFirstChild();
-
-    /**
-     *  The last child of this node. If there is no such node, this returns 
-     * <code>null</code> .
-     */
-    public Node getLastChild();
-
-    /**
-     *  The node immediately preceding this node. If there is no such node, 
-     * this returns <code>null</code> .
-     */
-    public Node getPreviousSibling();
-
-    /**
-     *  The node immediately following this node. If there is no such node, 
-     * this returns <code>null</code> .
-     */
-    public Node getNextSibling();
-
-    /**
-     *  A <code>NamedNodeMap</code> containing the attributes of this node (if 
-     * it is an <code>Element</code> ) or <code>null</code> otherwise. 
-     */
-    public NamedNodeMap getAttributes();
-
-    /**
-     *  The <code>Document</code> object associated with this node. This is 
-     * also the <code>Document</code> object used to create new nodes. When 
-     * this node is a <code>Document</code> or a <code>DocumentType</code> 
-     * which is not used with any <code>Document</code> yet, this is 
-     * <code>null</code> .
-     * @version DOM Level 2
-     */
-    public Document getOwnerDocument();
-
-    /**
-     *  Inserts the node <code>newChild</code> before the existing child node 
-     * <code>refChild</code> . If <code>refChild</code> is <code>null</code> 
-     * , insert <code>newChild</code> at the end of the list of children.
-     * <br> If <code>newChild</code> is a <code>DocumentFragment</code> 
-     * object, all of its children are inserted, in the same order, before 
-     * <code>refChild</code> . If the <code>newChild</code> is already in the 
-     * tree, it is first removed.
-     * @param newChild  The node to insert.
-     * @param refChild  The reference node, i.e., the node before which the 
-     *   new node must be inserted.
-     * @return  The node being inserted.
-     * @exception DOMException
-     *    HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does 
-     *   not allow children of the type of the <code>newChild</code> node, or 
-     *   if the node to insert is one of this node's ancestors.
-     *   <br> WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created 
-     *   from a different document than the one that created this node.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this node or the node 
-     *   being inserted is readonly.
-     *   <br> NOT_FOUND_ERR: Raised if <code>refChild</code> is not a child 
-     *   of this node.
-     */
-    public Node insertBefore(Node newChild, 
-                             Node refChild)
-                             throws DOMException;
-
-    /**
-     *  Replaces the child node <code>oldChild</code> with 
-     * <code>newChild</code> in the list of children, and returns the 
-     * <code>oldChild</code> node.
-     * <br> If <code>newChild</code> is a <code>DocumentFragment</code> object,
-     *  <code>oldChild</code> is replaced by all of the 
-     * <code>DocumentFragment</code> children, which are inserted in the same 
-     * order. If the <code>newChild</code> is already in the tree, it is 
-     * first removed.
-     * @param newChild  The new node to put in the child list.
-     * @param oldChild  The node being replaced in the list.
-     * @return  The node replaced.
-     * @exception DOMException
-     *    HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does 
-     *   not allow children of the type of the <code>newChild</code> node, or 
-     *   if the node to put in is one of this node's ancestors.
-     *   <br> WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created 
-     *   from a different document than the one that created this node.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this node or the new 
-     *   node is readonly.
-     *   <br> NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child 
-     *   of this node.
-     */
-    public Node replaceChild(Node newChild, 
-                             Node oldChild)
-                             throws DOMException;
-
-    /**
-     *  Removes the child node indicated by <code>oldChild</code> from the 
-     * list of children, and returns it.
-     * @param oldChild  The node being removed.
-     * @return  The node removed.
-     * @exception DOMException
-     *    NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     *   <br> NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child 
-     *   of this node.
-     */
-    public Node removeChild(Node oldChild)
-                            throws DOMException;
-
-    /**
-     *  Adds the node <code>newChild</code> to the end of the list of children 
-     * of this node. If the <code>newChild</code> is already in the tree, it 
-     * is first removed.
-     * @param newChild  The node to add. If it is a  
-     *   <code>DocumentFragment</code> object, the entire contents of the 
-     *   document fragment are moved into the child list of this node
-     * @return  The node added.
-     * @exception DOMException
-     *    HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does 
-     *   not allow children of the type of the <code>newChild</code> node, or 
-     *   if the node to append is one of this node's ancestors.
-     *   <br> WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created 
-     *   from a different document than the one that created this node.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this node or the node 
-     *   being appended is readonly.
-     */
-    public Node appendChild(Node newChild)
-                            throws DOMException;
-
-    /**
-     *  This is a convenience method to allow easy determination of whether a 
-     * node has any children.
-     * @return  <code>true</code> if the node has any children, 
-     *   <code>false</code> if the node has no children.
-     */
-    public boolean hasChildNodes();
-
-    /**
-     *  Returns a duplicate of this node, i.e., serves as a generic copy 
-     * constructor for nodes. The duplicate node has no parent; (
-     * <code>parentNode</code> returns <code>null</code> .).
-     * <br> Cloning an <code>Element</code> copies all attributes and their 
-     * values, including those generated by the XML processor to represent 
-     * defaulted attributes, but this method does not copy any text it 
-     * contains unless it is a deep clone, since the text is contained in a 
-     * child <code>Text</code> node. Cloning any other type of node simply 
-     * returns a copy of this node.
-     * <br> Note that cloning an immutable subtree results in a mutable copy, 
-     * but the children of an <code>EntityReference</code> clone are readonly.
-     * @param deep  If <code>true</code> , recursively clone the subtree under 
-     *   the specified node; if <code>false</code> , clone only the node 
-     *   itself (and its attributes, if it is an <code>Element</code> ).  
-     * @return  The duplicate node.
-     */
-    public Node cloneNode(boolean deep);
-
-    /**
-     *  Puts all <code>Text</code> nodes in the full depth of the sub-tree 
-     * underneath this <code>Node</code> , including attribute nodes, into a 
-     * "normal" form where only markup (e.g., tags, comments, processing 
-     * instructions, CDATA sections, and entity references) separates 
-     * <code>Text</code> nodes, i.e., there are neither adjacent 
-     * <code>Text</code> nodes nor empty <code>Text</code> nodes. This can be 
-     * used to ensure that the DOM view  of a document is the same as if it 
-     * were saved and re-loaded, and is useful when operations (such as 
-     * XPointer lookups) that depend on a particular document tree structure 
-     * are to be used. In cases where the document contains 
-     * <code>CDATASections</code> , the normalize operation alone may not be 
-     * sufficient, since XPointers do not differentiate between 
-     * <code>Text</code> nodes and <code>CDATASection</code> nodes.
-     * @since DOM Level 2
-     */
-    public void normalize();
-
-    /**
-     *  Tests whether the DOM implementation implements a specific feature and 
-     * that feature is supported by this node.
-     * @param feature  The name of the feature to test. This is the same name 
-     *   which can be passed to the method <code>hasFeature</code> on 
-     *   <code>DOMImplementation</code> .
-     * @param version  This is the version number of the feature to test. In 
-     *   Level 2, version 1, this is the string "2.0". If the version is not 
-     *   specified, supporting any version of the feature will cause the 
-     *   method to return <code>true</code> .
-     * @return  Returns <code>true</code> if the specified feature is supported
-     *    on this node, <code>false</code> otherwise.
-     * @since DOM Level 2
-     */
-    public boolean supports(String feature, 
-                            String version);
-
-    /**
-     *  The  namespace URI of this node, or <code>null</code> if it is 
-     * unspecified.
-     * <br> This is not a computed value that is the result of a namespace 
-     * lookup based on an examination of the namespace declarations in scope. 
-     * It is merely the namespace URI given at creation time.
-     * <br> For nodes of any type other than <code>ELEMENT_NODE</code> and 
-     * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1 
-     * method, such as <code>createElement</code> from the 
-     * <code>Document</code> interface, this is always <code>null</code> . 
-     * Per the  Namespaces in XML Specification  an attribute does not 
-     * inherit its namespace from the element it is attached to. If an 
-     * attribute is not explicitly given a namespace, it simply has no 
-     * namespace.
-     * @since DOM Level 2
-     */
-    public String getNamespaceURI();
-
-    /**
-     *  The  namespace prefix of this node, or <code>null</code> if it is 
-     * unspecified.
-     * <br> Note that setting this attribute, when permitted, changes the 
-     * <code>nodeName</code> attribute, which holds the  qualified name , as 
-     * well as the <code>tagName</code> and <code>name</code> attributes of 
-     * the <code>Element</code> and <code>Attr</code> interfaces, when 
-     * applicable.
-     * <br> Note also that changing the prefix of an attribute that is known to
-     *  have a default value, does not make a new attribute with the default 
-     * value and the original prefix appear, since the 
-     * <code>namespaceURI</code> and <code>localName</code> do not change.
-     * @exception DOMException
-     *    INVALID_CHARACTER_ERR: Raised if the specified prefix contains an 
-     *   illegal character.
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     *   <br> NAMESPACE_ERR: Raised if the specified <code>prefix</code> is 
-     *   malformed, if the <code>namespaceURI</code> of this node is 
-     *   <code>null</code> , if the specified prefix is "xml" and the 
-     *   <code>namespaceURI</code> of this node is different from 
-     *   "http://www.w3.org/XML/1998/namespace", if this node is an attribute 
-     *   and the specified prefix is "xmlns" and the <code>namespaceURI</code>
-     *    of this node is different from "http://www.w3.org/2000/xmlns/", or 
-     *   if this node is an attribute and the <code>qualifiedName</code> of 
-     *   this node is "xmlns"  .
-     * @since DOM Level 2
-     */
-    public String getPrefix();
-    public void setPrefix(String prefix)
-                            throws DOMException;
-
-    /**
-     *  Returns the local part of the  qualified name of this node.
-     * <br> For nodes created with a DOM Level 1 method, such as 
-     * <code>createElement</code> from the <code>Document</code> interface, 
-     * it is <code>null</code> .
-     * @since DOM Level 2
-     */
-    public String getLocalName();
-
-    /**
-     *  Returns whether this node (if it is an element) has any attributes.
-     * @return <code>true</code> if this node has any attributes, 
-     *   <code>false</code> otherwise.
-     * @since DOM Level 2
-     */
-    public boolean hasAttributes();
-}
-
diff --git a/src/org/w3c/dom/NodeList.java b/src/org/w3c/dom/NodeList.java
deleted file mode 100644
index 2b1107e..0000000
--- a/src/org/w3c/dom/NodeList.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  The <code>NodeList</code> interface provides the abstraction of an ordered 
- * collection of nodes, without defining or constraining how this collection 
- * is implemented.
- * <p> The items in the <code>NodeList</code> are accessible via an integral 
- * index, starting from 0. 
- */
-public interface NodeList {
-    /**
-     *  Returns the <code>index</code> th item in the collection. If 
-     * <code>index</code> is greater than or equal to the number of nodes in 
-     * the list, this returns <code>null</code> .
-     * @param index  Index into the collection.
-     * @return  The node at the <code>index</code> th position in the 
-     *   <code>NodeList</code> , or <code>null</code> if that is not a valid 
-     *   index.
-     */
-    public Node item(int index);
-
-    /**
-     *  The number of nodes in the list. The range of valid child node indices 
-     * is 0 to <code>length-1</code> inclusive. 
-     */
-    public int getLength();
-
-}
-
diff --git a/src/org/w3c/dom/Notation.java b/src/org/w3c/dom/Notation.java
deleted file mode 100644
index 7e074bd..0000000
--- a/src/org/w3c/dom/Notation.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  This interface represents a notation declared in the DTD. A notation 
- * either declares, by name, the format of an unparsed entity (see section 4.7
- *  of the XML 1.0 specification), or is used for formal declaration of 
- * processing instruction targets (see section 2.6 of the XML 1.0 
- * specification). The <code>nodeName</code> attribute inherited from 
- * <code>Node</code> is set to the declared name of the notation.
- * <p> The DOM Level 1 does not support editing <code>Notation</code> nodes; 
- * they are therefore readonly.
- * <p> A <code>Notation</code> node does not have any parent.
- */
-public interface Notation extends Node {
-    /**
-     *  The public identifier of this notation. If the  public identifier was 
-     * not specified, this is <code>null</code> .
-     */
-    public String getPublicId();
-
-    /**
-     *  The system identifier of this notation. If the  system identifier was 
-     * not specified, this is <code>null</code> .
-     */
-    public String getSystemId();
-
-}
-
diff --git a/src/org/w3c/dom/ProcessingInstruction.java b/src/org/w3c/dom/ProcessingInstruction.java
deleted file mode 100644
index ac5aa1d..0000000
--- a/src/org/w3c/dom/ProcessingInstruction.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  The <code>ProcessingInstruction</code> interface represents a  "processing 
- * instruction", used in XML as a way to keep processor-specific information 
- * in the text of the document.
- */
-public interface ProcessingInstruction extends Node {
-    /**
-     *  The target of this processing instruction. XML defines this as being 
-     * the first token following the markup that begins the processing 
-     * instruction.
-     */
-    public String getTarget();
-
-    /**
-     *  The content of this processing instruction. This is from the first non 
-     * white space character after the target to the character immediately 
-     * preceding the <code>?&gt;</code> .
-     * @exception DOMException
-     *    NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
-     */
-    public String getData();
-    public void setData(String data)
-                          throws DOMException;
-
-}
-
diff --git a/src/org/w3c/dom/Text.java b/src/org/w3c/dom/Text.java
deleted file mode 100644
index eeba78e..0000000
--- a/src/org/w3c/dom/Text.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom;
-
-/**
- *  The <code>Text</code> interface inherits from <code>CharacterData</code> 
- * and represents the textual content (termed  character  data in XML) of an 
- * <code>Element</code> or <code>Attr</code> .  If there is no markup inside 
- * an element's content, the text is contained in a single object 
- * implementing the <code>Text</code> interface that is the only child of the 
- * element. If there is markup, it is parsed into the  information items 
- * (elements,  comments, etc.) and <code>Text</code>  nodes that form the 
- * list of children of the element.
- * <p> When a document is first made available via the DOM, there is  only one 
- * <code>Text</code> node for each block of text. Users may create  adjacent 
- * <code>Text</code> nodes that represent the  contents of a given element 
- * without any intervening markup, but should be aware that there is no way 
- * to represent the separations between these nodes in XML or HTML, so they 
- * will not (in general) persist between DOM editing sessions. The 
- * <code>normalize()</code> method on <code>Element</code> merges any such 
- * adjacent <code>Text</code> objects into a single node for each block of 
- * text.
- */
-public interface Text extends CharacterData {
-    /**
-     *  Breaks this node into two  nodes at the specified <code>offset</code> 
-     * , keeping both in the tree as siblings. This node then only contains 
-     * all the content up to the <code>offset</code> point. A new node of the 
-     * same type, which is inserted as the next sibling of this node, 
-     * contains all the content at and after the <code>offset</code> point. 
-     * When the <code>offset</code> is equal to the length of this node, the 
-     * new node has no data.
-     * @param offset  The  16-bit unit offset at which to split, starting from 
-     *   <code>0</code> .
-     * @return  The new node, of the same type as this node.
-     * @exception DOMException
-     *    INDEX_SIZE_ERR: Raised if the specified offset is negative or 
-     *   greater than the number of 16-bit units in <code>data</code> .
-     *   <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     */
-    public Text splitText(int offset)
-                          throws DOMException;
-
-}
-
diff --git a/src/org/w3c/dom/events/DocumentEvent.java b/src/org/w3c/dom/events/DocumentEvent.java
deleted file mode 100644
index 3ccfa61..0000000
--- a/src/org/w3c/dom/events/DocumentEvent.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.events;
-
-import org.w3c.dom.DOMException;
-
-/**
- *  The <code>DocumentEvent</code> interface provides a mechanism by which the 
- * user can create an Event of a type supported by the implementation. It is 
- * expected that the <code>DocumentEvent</code> interface will be implemented 
- * on the same object which implements the <code>Document</code> interface in 
- * an implementation which supports the Event model. 
- * @since DOM Level 2
- */
-public interface DocumentEvent {
-    /**
-     * 
-     * @param eventType  The <code>eventType</code> parameter specifies the 
-     *   type of <code>Event</code> interface to be created.  If the 
-     *   <code>Event</code> interface specified is supported by the 
-     *   implementation  this method will return a new <code>Event</code> of 
-     *   the interface type requested.  If the  <code>Event</code> is to be 
-     *   dispatched via the <code>dispatchEvent</code> method the  
-     *   appropriate event init method must be called after creation in order 
-     *   to initialize the <code>Event</code> 's values.  As an example, a 
-     *   user wishing to synthesize some kind of  <code>UIEvent</code> would 
-     *   call <code>createEvent</code> with the parameter "UIEvents".  The  
-     *   <code>initUIEvent</code> method could then be called on the newly 
-     *   created <code>UIEvent</code> to set the specific type of UIEvent to 
-     *   be dispatched and set its context information. The 
-     *   <code>createEvent</code> method is used in creating 
-     *   <code>Event</code> s when it is either  inconvenient or unnecessary 
-     *   for the user to create an <code>Event</code> themselves.  In cases 
-     *   where the implementation provided <code>Event</code> is 
-     *   insufficient, users may supply their own <code>Event</code> 
-     *   implementations for use with the <code>dispatchEvent</code> method.
-     * @return  The newly created <code>Event</code>
-     * @exception DOMException
-     *    NOT_SUPPORTED_ERR: Raised if the implementation does not support 
-     *   the type of <code>Event</code> interface requested
-     */
-    public Event createEvent(String eventType)
-                             throws DOMException;
-
-}
-
diff --git a/src/org/w3c/dom/events/Event.java b/src/org/w3c/dom/events/Event.java
deleted file mode 100644
index 9deac86..0000000
--- a/src/org/w3c/dom/events/Event.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.events;
-
-import org.w3c.dom.Node;
-
-/**
- *  The <code>Event</code> interface is used to provide contextual information 
- * about an event to the handler processing the event.  An object which 
- * implements the <code>Event</code> interface is generally passed as the 
- * first parameter to an event handler.  More specific  context information 
- * is passed to event handlers by deriving additional interfaces from  
- * <code>Event</code> which contain information directly relating to the type 
- * of event they accompany.  These derived interfaces are also implemented by 
- * the object passed to the event listener. 
- * @since DOM Level 2
- */
-public interface Event {
-    // PhaseType
-    public static final short CAPTURING_PHASE           = 1;
-    public static final short AT_TARGET                 = 2;
-    public static final short BUBBLING_PHASE            = 3;
-
-    /**
-     *  The <code>type</code> property represents the event name as a string 
-     * property. The string must be an  XML name .
-     */
-    public String getType();
-
-    /**
-     *  The <code>target</code> property indicates the <code>EventTarget</code>
-     *  to which the event  was originally dispatched. 
-     */
-    public EventTarget getTarget();
-
-    /**
-     *  The <code>currentNode</code> property indicates the <code>Node</code> 
-     * whose <code>EventListeners</code> are currently being processed.  This 
-     * is particularly useful during capturing and bubbling. 
-     */
-    public Node getCurrentNode();
-
-    /**
-     *  The <code>eventPhase</code> property indicates which phase of event 
-     * flow is currently  being evaluated. 
-     */
-    public short getEventPhase();
-
-    /**
-     *  The <code>bubbles</code> property indicates whether or not an event is 
-     * a bubbling event.  If the event can bubble the value is true, else the 
-     * value is false. 
-     */
-    public boolean getBubbles();
-
-    /**
-     *  The <code>cancelable</code> property indicates whether or not an event 
-     * can have its default action prevented.  If the default action can be 
-     * prevented the value is true, else the value is false. 
-     */
-    public boolean getCancelable();
-
-    /**
-     *  The <code>timeStamp</code> specifies the time (in milliseconds relative
-     *  to the epoch) at which the event was created. Due to the fact that 
-     * some systems may not provide this information the value of 
-     * <code>timeStamp</code> may be not available for all events. When not 
-     * available, a value of 0 will be returned. Examples of epoch time are 
-     * the time of the system start or 0:0:0 UTC 1st January 1970. 
-     */
-    public long getTimeStamp();
-
-    /**
-     *  The <code>stopPropagation</code> method is used prevent further 
-     * propagation of an event during event flow. If this method is called by 
-     * any <code>EventListener</code> the event will cease propagating 
-     * through the tree.  The event will complete dispatch to all listeners 
-     * on the current <code>EventTarget</code> before event flow stops.  This 
-     * method may be used during any stage of event flow.
-     */
-    public void stopPropagation();
-
-    /**
-     *  If an event is cancelable, the <code>preventDefault</code> method is 
-     * used to signify that the event is to be canceled, meaning any default 
-     * action normally taken by the implementation as a result of the event 
-     * will not occur.  If, during any stage of event flow, the 
-     * <code>preventDefault</code> method is called the event is canceled. 
-     * Any default action associated with the event will not occur.  Calling 
-     * this method for a non-cancelable event has no effect.  Once 
-     * <code>preventDefault</code> has been called it will remain in effect 
-     * throughout the remainder of the event's propagation.  This method may 
-     * be used during any stage of event flow. 
-     */
-    public void preventDefault();
-
-    /**
-     *  The <code>initEvent</code> method is used to initialize the value of 
-     * an <code>Event</code> created through the <code>DocumentEvent</code> 
-     * interface.  This method may only be called before the 
-     * <code>Event</code> has been dispatched via the 
-     * <code>dispatchEvent</code> method, though it may be called multiple 
-     * times during that phase if necessary.  If called multiple times the 
-     * final invocation takes precedence.  If called from a subclass of 
-     * <code>Event</code> interface only the values specified in the 
-     * <code>initEvent</code> method are modified, all other properties are 
-     * left unchanged.
-     * @param eventTypeArg  Specifies the event type.  This type may be any 
-     *   event type currently defined in this specification or a new event 
-     *   type.. The string must be an  XML name .  Any new event type must 
-     *   not begin with any upper, lower, or mixed case version  of the 
-     *   string "DOM".  This prefix is reserved for future DOM event sets.
-     * @param canBubbleArg  Specifies whether or not the event can bubble.
-     * @param cancelableArg  Specifies whether or not the event's default  
-     *   action can be prevented.
-     */
-    public void initEvent(String eventTypeArg, 
-                          boolean canBubbleArg, 
-                          boolean cancelableArg);
-
-}
-
diff --git a/src/org/w3c/dom/events/EventException.java b/src/org/w3c/dom/events/EventException.java
deleted file mode 100644
index 3dccf77..0000000
--- a/src/org/w3c/dom/events/EventException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.events;
-
-/**
- *  Event operations may throw an <code>EventException</code> as specified in 
- * their method descriptions. 
- */
-public class EventException extends RuntimeException {
-    public EventException(short code, String message) {
-       super(message);
-       this.code = code;
-    }
-    public short   code;
-    // EventExceptionCode
-    public static final short UNSPECIFIED_EVENT_TYPE_ERR = 0;
-
-}
-
diff --git a/src/org/w3c/dom/events/EventListener.java b/src/org/w3c/dom/events/EventListener.java
deleted file mode 100644
index 6074ea5..0000000
--- a/src/org/w3c/dom/events/EventListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.events;
-
-/**
- *  The <code>EventListener</code> interface is the primary method for 
- * handling events. Users implement the <code>EventListener</code> interface 
- * and register their listener on an <code>EventTarget</code> using the 
- * <code>AddEventListener</code> method. The users should also remove their 
- * <code>EventListener</code> from its <code>EventTarget</code> after they 
- * have completed using the listener. 
- * @since DOM Level 2
- */
-public interface EventListener {
-    /**
-     *  This method is called whenever an event occurs of the type for which 
-     * the <code>EventListener</code> interface was registered. 
-     * @param evt  The <code>Event</code> contains contextual information 
-     *   about the event. It also contains the <code>stopPropagation</code> 
-     *   and  <code>preventDefault</code> methods which are used in 
-     *   determining the event's flow and default action. 
-     */
-    public void handleEvent(Event evt);
-
-}
-
diff --git a/src/org/w3c/dom/events/EventTarget.java b/src/org/w3c/dom/events/EventTarget.java
deleted file mode 100644
index e6d20ea..0000000
--- a/src/org/w3c/dom/events/EventTarget.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.events;
-
-/**
- *  The <code>EventTarget</code> interface is implemented by all 
- * <code>Nodes</code> in  an implementation which supports the DOM Event 
- * Model.  The interface allows registration and removal of 
- * <code>EventListeners</code> on an <code>EventTarget</code> and dispatch of 
- * events to that <code>EventTarget</code> .
- * @since DOM Level 2
- */
-public interface EventTarget {
-    /**
-     *  This method allows the registration of event listeners on the event 
-     * target.  If an <code>EventListener</code> is added to an 
-     * <code>EventTarget</code> which is  currently processing an event the 
-     * new listener will not be triggered by the current event. 
-     * <br> If multiple identical <code>EventListener</code> s are registered 
-     * on the same <code>EventTarget</code> with the same parameters the 
-     * duplicate instances are discarded. They do not cause the 
-     * <code>EventListener</code> to be called twice and since they are  
-     * discarded they do not need to be removed with the 
-     * <code>removeEventListener</code> method. 
-     * @param type  The event type for which the user is registering
-     * @param listener  The <code>listener</code> parameter takes an interface 
-     *   implemented by the user which contains the methods to be called when 
-     *   the event occurs.
-     * @param useCapture  If true, <code>useCapture</code> indicates that the 
-     *   user wishes to initiate capture.  After initiating capture, all 
-     *   events of the specified type will be  dispatched to the registered 
-     *   <code>EventListener</code> before being dispatched to any 
-     *   <code>EventTargets</code> beneath them in the tree.  Events which 
-     *   are bubbling upward through the tree will not trigger an 
-     *   <code>EventListener</code> designated to use capture.
-     */
-    public void addEventListener(String type, 
-                                 EventListener listener, 
-                                 boolean useCapture);
-
-    /**
-     *  This method allows the removal of event listeners from the event 
-     * target.  If an <code>EventListener</code> is removed from an 
-     * <code>EventTarget</code> while it is  processing an event, it will 
-     * complete its current actions but will not be triggered again during 
-     * any later stages of event flow.
-     * <br> If an <code>EventListener</code> is removed from an 
-     * <code>EventTarget</code> which is  currently processing an event the 
-     * removed listener will still be triggered by the current event.
-     * <br> Calling <code>removeEventListener</code> with arguments which do 
-     * not identify any currently registered <code>EventListener</code> on 
-     * the <code>EventTarget</code> has no effect.
-     * @param type  Specifies the event type of the <code>EventListener</code> 
-     *   being removed. 
-     * @param listener  The <code>EventListener</code> parameter indicates the 
-     *   <code>EventListener</code> to be removed. 
-     * @param useCapture  Specifies whether the <code>EventListener</code> 
-     *   being removed was registered as a capturing listener or not.  If a 
-     *   listener was registered twice, one with capture and one without, 
-     *   each must be removed separately.  Removal of a capturing listener 
-     *   does not affect a non-capturing version of the same listener, and 
-     *   vice versa. 
-     */
-    public void removeEventListener(String type, 
-                                    EventListener listener, 
-                                    boolean useCapture);
-
-    /**
-     *  This method allows the dispatch of events into the implementations 
-     * event model.  Events dispatched in this manner will have the same 
-     * capturing and bubbling behavior as events dispatched directly by the 
-     * implementation.  The target of the event is the 
-     * <code>EventTarget</code> on which <code>dispatchEvent</code> is called.
-     *  
-     * @param evt  Specifies the event type, behavior, and contextual 
-     *   information to be used in processing the event.
-     * @return  The return value of <code>dispatchEvent</code> indicates 
-     *   whether any of the listeners which handled the event called 
-     *   <code>preventDefault</code> .  If <code>preventDefault</code> was 
-     *   called the value is false, else the value is true. 
-     * @exception EventException
-     *    UNSPECIFIED_EVENT_TYPE_ERR: Raised if the <code>Event</code> 's 
-     *   type was not specified by initializing the event before 
-     *   <code>dispatchEvent</code> was called. Specification of the 
-     *   <code>Event</code> 's type as <code>null</code> or an empty string 
-     *   will also trigger this exception.
-     */
-    public boolean dispatchEvent(Event evt)
-                                 throws EventException;
-
-}
-
diff --git a/src/org/w3c/dom/events/Makefile b/src/org/w3c/dom/events/Makefile
deleted file mode 100644
index 39eacd0..0000000
--- a/src/org/w3c/dom/events/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# Makefile for directory ./org/w3c/dom/events
-
-TARGETS=\
-     DocumentEvent.class\
-     Event.class\
-     EventException.class\
-     EventListener.class\
-     EventTarget.class\
-     MutationEvent.class
-
-DIRS= 
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/w3c/dom/events/MutationEvent.java b/src/org/w3c/dom/events/MutationEvent.java
deleted file mode 100644
index 89725b3..0000000
--- a/src/org/w3c/dom/events/MutationEvent.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.events;
-
-import org.w3c.dom.Node;
-
-/**
- *  The <code>MutationEvent</code> interface provides specific contextual  
- * information associated with Mutation events. 
- * @since DOM Level 2
- */
-public interface MutationEvent extends Event {
-    /**
-     *  <code>relatedNode</code> is used to identify a secondary node related 
-     * to a mutation event. For example, if a mutation event is dispatched to 
-     * a node indicating that its parent has changed, the 
-     * <code>relatedNode</code> is the changed parent.  If an event is instead
-     *  dispatch to a subtree indicating a node was changed within it, the 
-     * <code>relatedNode</code> is the changed node. 
-     */
-    public Node getRelatedNode();
-
-    /**
-     *  <code>prevValue</code> indicates the previous value of the 
-     * <code>Attr</code> node in DOMAttrModified events, and of the 
-     * <code>CharacterData</code> node in DOMCharDataModified events. 
-     */
-    public String getPrevValue();
-
-    /**
-     *  <code>newValue</code> indicates the new value of the <code>Attr</code> 
-     * node in DOMAttrModified events, and of the <code>CharacterData</code> 
-     * node in DOMCharDataModified events. 
-     */
-    public String getNewValue();
-
-    /**
-     *  <code>attrName</code> indicates the name of the changed 
-     * <code>Attr</code> node in a DOMAttrModified event. 
-     */
-    public String getAttrName();
-
-    /**
-     *  The <code>initMutationEvent</code> method is used to initialize the 
-     * value of a <code>MutationEvent</code> created through the 
-     * <code>DocumentEvent</code> interface.  This method may only be called 
-     * before the <code>MutationEvent</code> has been dispatched via the 
-     * <code>dispatchEvent</code> method, though it may be called multiple 
-     * times during that phase if necessary.  If called multiple times, the 
-     * final invocation takes precedence.
-     * @param typeArg  Specifies the event type.
-     * @param canBubbleArg  Specifies whether or not the event can bubble.
-     * @param cancelableArg  Specifies whether or not the event's default  
-     *   action can be prevented.
-     * @param relatedNodeArg  Specifies the <code>Event</code> 's related Node
-     * @param prevValueArg  Specifies the <code>Event</code> 's 
-     *   <code>prevValue</code> property
-     * @param newValueArg  Specifies the <code>Event</code> 's 
-     *   <code>newValue</code> property
-     * @param attrNameArg  Specifies the <code>Event</code> 's 
-     *   <code>attrName</code> property
-     */
-    public void initMutationEvent(String typeArg, 
-                                  boolean canBubbleArg, 
-                                  boolean cancelableArg, 
-                                  Node relatedNodeArg, 
-                                  String prevValueArg, 
-                                  String newValueArg, 
-                                  String attrNameArg);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLAnchorElement.java b/src/org/w3c/dom/html/HTMLAnchorElement.java
deleted file mode 100644
index 8dcd6ec..0000000
--- a/src/org/w3c/dom/html/HTMLAnchorElement.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  The anchor element. See the  A element definition in HTML 4.0.
- */
-public interface HTMLAnchorElement extends HTMLElement {
-    /**
-     *  A single character access key to give access to the form control. See 
-     * the  accesskey attribute definition in HTML 4.0.
-     */
-    public String getAccessKey();
-    public void setAccessKey(String accessKey);
-
-    /**
-     *  The character encoding of the linked resource. See the  charset 
-     * attribute definition in HTML 4.0.
-     */
-    public String getCharset();
-    public void setCharset(String charset);
-
-    /**
-     *  Comma-separated list of lengths, defining an active region geometry. 
-     * See also <code>shape</code> for the shape of the region. See the  
-     * coords attribute definition in HTML 4.0.
-     */
-    public String getCoords();
-    public void setCoords(String coords);
-
-    /**
-     *  The URI of the linked resource. See the  href attribute definition in 
-     * HTML 4.0.
-     */
-    public String getHref();
-    public void setHref(String href);
-
-    /**
-     *  Language code of the linked resource. See the  hreflang attribute 
-     * definition in HTML 4.0.
-     */
-    public String getHreflang();
-    public void setHreflang(String hreflang);
-
-    /**
-     *  Anchor name. See the  name attribute definition in HTML 4.0.
-     */
-    public String getName();
-    public void setName(String name);
-
-    /**
-     *  Forward link type. See the  rel attribute definition in HTML 4.0.
-     */
-    public String getRel();
-    public void setRel(String rel);
-
-    /**
-     *  Reverse link type. See the  rev attribute definition in HTML 4.0.
-     */
-    public String getRev();
-    public void setRev(String rev);
-
-    /**
-     *  The shape of the active area. The coordinates are given by 
-     * <code>coords</code> . See the  shape attribute definition in HTML 4.0.
-     */
-    public String getShape();
-    public void setShape(String shape);
-
-    /**
-     *  Index that represents the element's position in the tabbing order. See 
-     * the  tabindex attribute definition in HTML 4.0.
-     */
-    public int getTabIndex();
-    public void setTabIndex(int tabIndex);
-
-    /**
-     *  Frame to render the resource in. See the  target attribute definition 
-     * in HTML 4.0.
-     */
-    public String getTarget();
-    public void setTarget(String target);
-
-    /**
-     *  Advisory content type. See the  type attribute definition in HTML 4.0.
-     */
-    public String getType();
-    public void setType(String type);
-
-    /**
-     *  Removes keyboard focus from this element.
-     */
-    public void blur();
-
-    /**
-     *  Gives keyboard focus to this element.
-     */
-    public void focus();
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLAppletElement.java b/src/org/w3c/dom/html/HTMLAppletElement.java
deleted file mode 100644
index 89312bc..0000000
--- a/src/org/w3c/dom/html/HTMLAppletElement.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  An embedded Java applet. See the  APPLET element definition in HTML 4.0. 
- * This element is deprecated in HTML 4.0.
- */
-public interface HTMLAppletElement extends HTMLElement {
-    /**
-     *  Aligns this object (vertically or horizontally)  with respect to its 
-     * surrounding text. See the  align attribute definition in HTML 4.0. 
-     * This attribute is deprecated in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-    /**
-     *  Alternate text for user agents not rendering the normal content of 
-     * this element. See the  alt attribute definition in HTML 4.0. This 
-     * attribute is deprecated in HTML 4.0.
-     */
-    public String getAlt();
-    public void setAlt(String alt);
-
-    /**
-     *  Comma-separated archive list. See the  archive attribute definition in 
-     * HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getArchive();
-    public void setArchive(String archive);
-
-    /**
-     *  Applet class file.  See the  code attribute definition in HTML 4.0. 
-     * This attribute is deprecated in HTML 4.0.
-     */
-    public String getCode();
-    public void setCode(String code);
-
-    /**
-     *  Optional base URI for applet. See the  codebase attribute definition 
-     * in HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getCodeBase();
-    public void setCodeBase(String codeBase);
-
-    /**
-     *  Override height. See the  height attribute definition in HTML 4.0. 
-     * This attribute is deprecated in HTML 4.0.
-     */
-    public String getHeight();
-    public void setHeight(String height);
-
-    /**
-     *  Horizontal space to the left and right of this image, applet, or 
-     * object. See the  hspace attribute definition in HTML 4.0. This 
-     * attribute is deprecated in HTML 4.0.
-     */
-    public String getHspace();
-    public void setHspace(String hspace);
-
-    /**
-     *  The name of the applet. See the  name attribute definition in HTML 
-     * 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getName();
-    public void setName(String name);
-
-    /**
-     *  Serialized applet file. See the  object attribute definition in HTML 
-     * 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getObject();
-    public void setObject(String object);
-
-    /**
-     *  Vertical space above and below this image, applet, or object. See the  
-     * vspace attribute definition in HTML 4.0. This attribute is deprecated 
-     * in HTML 4.0.
-     */
-    public String getVspace();
-    public void setVspace(String vspace);
-
-    /**
-     *  Override width. See the  width attribute definition in HTML 4.0. This 
-     * attribute is deprecated in HTML 4.0.
-     */
-    public String getWidth();
-    public void setWidth(String width);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLAreaElement.java b/src/org/w3c/dom/html/HTMLAreaElement.java
deleted file mode 100644
index 4f884a4..0000000
--- a/src/org/w3c/dom/html/HTMLAreaElement.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Client-side image map area definition. See the  AREA element definition in 
- * HTML 4.0.
- */
-public interface HTMLAreaElement extends HTMLElement {
-    /**
-     *  A single character access key to give access to the form control. See 
-     * the  accesskey attribute definition in HTML 4.0.
-     */
-    public String getAccessKey();
-    public void setAccessKey(String accessKey);
-
-    /**
-     *  Alternate text for user agents not rendering the normal content of 
-     * this element. See the  alt attribute definition in HTML 4.0.
-     */
-    public String getAlt();
-    public void setAlt(String alt);
-
-    /**
-     *  Comma-separated list of lengths, defining an active region geometry. 
-     * See also <code>shape</code> for the shape of the region. See the  
-     * coords attribute definition in HTML 4.0.
-     */
-    public String getCoords();
-    public void setCoords(String coords);
-
-    /**
-     *  The URI of the linked resource. See the  href attribute definition in 
-     * HTML 4.0.
-     */
-    public String getHref();
-    public void setHref(String href);
-
-    /**
-     *  Specifies that this area is inactive, i.e., has no associated action. 
-     * See the  nohref attribute definition in HTML 4.0.
-     */
-    public boolean getNoHref();
-    public void setNoHref(boolean noHref);
-
-    /**
-     *  The shape of the active area. The coordinates are given by 
-     * <code>coords</code> . See the  shape attribute definition in HTML 4.0.
-     */
-    public String getShape();
-    public void setShape(String shape);
-
-    /**
-     *  Index that represents the element's position in the tabbing order. See 
-     * the  tabindex attribute definition in HTML 4.0.
-     */
-    public int getTabIndex();
-    public void setTabIndex(int tabIndex);
-
-    /**
-     *  Frame to render the resource in. See the  target attribute definition 
-     * in HTML 4.0.
-     */
-    public String getTarget();
-    public void setTarget(String target);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLBRElement.java b/src/org/w3c/dom/html/HTMLBRElement.java
deleted file mode 100644
index efa59a9..0000000
--- a/src/org/w3c/dom/html/HTMLBRElement.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Force a line break. See the  BR element definition in HTML 4.0.
- */
-public interface HTMLBRElement extends HTMLElement {
-    /**
-     *  Control flow of text around floats. See the  clear attribute definition
-     *  in HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getClear();
-    public void setClear(String clear);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLBaseElement.java b/src/org/w3c/dom/html/HTMLBaseElement.java
deleted file mode 100644
index 1dee8c4..0000000
--- a/src/org/w3c/dom/html/HTMLBaseElement.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Document base URI. See the  BASE element definition in HTML 4.0.
- */
-public interface HTMLBaseElement extends HTMLElement {
-    /**
-     *  The base URI. See the  href attribute definition in HTML 4.0.
-     */
-    public String getHref();
-    public void setHref(String href);
-
-    /**
-     *  The default target frame. See the  target attribute definition in HTML 
-     * 4.0.
-     */
-    public String getTarget();
-    public void setTarget(String target);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLBaseFontElement.java b/src/org/w3c/dom/html/HTMLBaseFontElement.java
deleted file mode 100644
index 4ec4abc..0000000
--- a/src/org/w3c/dom/html/HTMLBaseFontElement.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Base font. See the  BASEFONT element definition in HTML 4.0. This element 
- * is deprecated in HTML 4.0.
- */
-public interface HTMLBaseFontElement extends HTMLElement {
-    /**
-     *  Font color. See the  color attribute definition in HTML 4.0. This 
-     * attribute is deprecated in HTML 4.0.
-     */
-    public String getColor();
-    public void setColor(String color);
-
-    /**
-     *  Font face identifier. See the  face attribute definition in HTML 4.0. 
-     * This attribute is deprecated in HTML 4.0.
-     */
-    public String getFace();
-    public void setFace(String face);
-
-    /**
-     *  Font size. See the  size attribute definition in HTML 4.0. This 
-     * attribute is deprecated in HTML 4.0.
-     */
-    public String getSize();
-    public void setSize(String size);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLBodyElement.java b/src/org/w3c/dom/html/HTMLBodyElement.java
deleted file mode 100644
index 47dd56c..0000000
--- a/src/org/w3c/dom/html/HTMLBodyElement.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  The HTML document body. This element is always present in the DOM API, 
- * even if the tags are not present in the source document. See the  BODY 
- * element definition in HTML 4.0.
- */
-public interface HTMLBodyElement extends HTMLElement {
-    /**
-     *  Color of active links (after mouse-button down, but before 
-     * mouse-button up). See the  alink attribute definition in HTML 4.0. 
-     * This attribute is deprecated in HTML 4.0.
-     */
-    public String getALink();
-    public void setALink(String aLink);
-
-    /**
-     *  URI of the background texture tile image. See the  background 
-     * attribute definition in HTML 4.0. This attribute is deprecated in HTML 
-     * 4.0.
-     */
-    public String getBackground();
-    public void setBackground(String background);
-
-    /**
-     *  Document background color. See the  bgcolor attribute definition in 
-     * HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getBgColor();
-    public void setBgColor(String bgColor);
-
-    /**
-     *  Color of links that are not active and unvisited. See the  link 
-     * attribute definition in HTML 4.0. This attribute is deprecated in HTML 
-     * 4.0.
-     */
-    public String getLink();
-    public void setLink(String link);
-
-    /**
-     *  Document text color. See the  text attribute definition in HTML 4.0. 
-     * This attribute is deprecated in HTML 4.0.
-     */
-    public String getText();
-    public void setText(String text);
-
-    /**
-     *  Color of links that have been visited by the user. See the  vlink 
-     * attribute definition in HTML 4.0. This attribute is deprecated in HTML 
-     * 4.0.
-     */
-    public String getVLink();
-    public void setVLink(String vLink);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLButtonElement.java b/src/org/w3c/dom/html/HTMLButtonElement.java
deleted file mode 100644
index cb9ecb1..0000000
--- a/src/org/w3c/dom/html/HTMLButtonElement.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Push button. See the  BUTTON element definition in HTML 4.0.
- */
-public interface HTMLButtonElement extends HTMLElement {
-    /**
-     *  Returns the <code>FORM</code> element containing this control. Returns 
-     * <code>null</code> if this control is not within the context of a form. 
-     */
-    public HTMLFormElement getForm();
-
-    /**
-     *  A single character access key to give access to the form control. See 
-     * the  accesskey attribute definition in HTML 4.0.
-     */
-    public String getAccessKey();
-    public void setAccessKey(String accessKey);
-
-    /**
-     *  The control is unavailable in this context. See the  disabled 
-     * attribute definition in HTML 4.0.
-     */
-    public boolean getDisabled();
-    public void setDisabled(boolean disabled);
-
-    /**
-     *  Form control or object name when submitted with a form. See the  name 
-     * attribute definition in HTML 4.0.
-     */
-    public String getName();
-    public void setName(String name);
-
-    /**
-     *  Index that represents the element's position in the tabbing order. See 
-     * the  tabindex attribute definition in HTML 4.0.
-     */
-    public int getTabIndex();
-    public void setTabIndex(int tabIndex);
-
-    /**
-     *  The type of button. See the  type attribute definition in HTML 4.0.
-     */
-    public String getType();
-
-    /**
-     *  The current form control value. See the  value attribute definition in 
-     * HTML 4.0.
-     */
-    public String getValue();
-    public void setValue(String value);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLCollection.java b/src/org/w3c/dom/html/HTMLCollection.java
deleted file mode 100644
index ce6bd69..0000000
--- a/src/org/w3c/dom/html/HTMLCollection.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-import org.w3c.dom.Node;
-
-/**
- *  An <code>HTMLCollection</code> is a list of nodes. An individual node may 
- * be accessed by either ordinal index or the node's<code>name</code> or 
- * <code>id</code> attributes.  Note: Collections in the HTML DOM are assumed 
- * to be  live meaning that they are automatically updated when the 
- * underlying document is changed. 
- */
-public interface HTMLCollection {
-    /**
-     *  This attribute specifies the length or  size of the list. 
-     */
-    public int getLength();
-
-    /**
-     *  This method retrieves a node specified by ordinal index. Nodes are 
-     * numbered in tree order (depth-first traversal order).
-     * @param index  The index of the node to be fetched. The index origin is 
-     *   0.
-     * @return  The <code>Node</code> at the corresponding position upon 
-     *   success. A value of <code>null</code> is returned if the index is 
-     *   out of range. 
-     */
-    public Node item(int index);
-
-    /**
-     *  This method retrieves a <code>Node</code> using a name. It first 
-     * searches for a <code>Node</code> with a matching <code>id</code> 
-     * attribute. If it doesn't find one, it then searches for a 
-     * <code>Node</code> with a matching <code>name</code> attribute, but 
-     * only on those elements that are allowed a name attribute. 
-     * @param name  The name of the <code>Node</code> to be fetched.
-     * @return  The <code>Node</code> with a <code>name</code> or 
-     *   <code>id</code> attribute whose value corresponds to the specified 
-     *   string. Upon failure (e.g., no node with this name exists), returns 
-     *   <code>null</code> .
-     */
-    public Node namedItem(String name);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLDListElement.java b/src/org/w3c/dom/html/HTMLDListElement.java
deleted file mode 100644
index 9ce4e05..0000000
--- a/src/org/w3c/dom/html/HTMLDListElement.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Definition list. See the  DL element definition in HTML 4.0.
- */
-public interface HTMLDListElement extends HTMLElement {
-    /**
-     *  Reduce spacing between list items. See the  compact attribute 
-     * definition in HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public boolean getCompact();
-    public void setCompact(boolean compact);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLDOMImplementation.java b/src/org/w3c/dom/html/HTMLDOMImplementation.java
deleted file mode 100644
index c6ed97d..0000000
--- a/src/org/w3c/dom/html/HTMLDOMImplementation.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-import org.w3c.dom.DOMImplementation;
-
-/**
- *  The <code>HTMLDOMImplementation</code> interface extends the 
- * <code>DOMImplementation</code> interface with a method for creating an 
- * HTML document instance.
- * @since DOM Level 2
- */
-public interface HTMLDOMImplementation extends DOMImplementation {
-    /**
-     *  Creates an <code>HTMLDocument</code> object with the minimal tree made 
-     * of the following elements: <code>HTML</code> , <code>HEAD</code> , 
-     * <code>TITLE</code> , and <code>BODY</code> .
-     * @param title  The title of the document to be set as the content of the 
-     *   <code>TITLE</code> element, through a child <code>Text</code> node.
-     * @return  A new <code>HTMLDocument</code> object.
-     */
-    public HTMLDocument createHTMLDocument(String title);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLDirectoryElement.java b/src/org/w3c/dom/html/HTMLDirectoryElement.java
deleted file mode 100644
index 6171504..0000000
--- a/src/org/w3c/dom/html/HTMLDirectoryElement.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Directory list. See the  DIR element definition in HTML 4.0. This element 
- * is deprecated in HTML 4.0.
- */
-public interface HTMLDirectoryElement extends HTMLElement {
-    /**
-     *  Reduce spacing between list items. See the  compact attribute 
-     * definition in HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public boolean getCompact();
-    public void setCompact(boolean compact);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLDivElement.java b/src/org/w3c/dom/html/HTMLDivElement.java
deleted file mode 100644
index d7e0fde..0000000
--- a/src/org/w3c/dom/html/HTMLDivElement.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Generic block container. See the  DIV element definition in HTML 4.0.
- */
-public interface HTMLDivElement extends HTMLElement {
-    /**
-     *  Horizontal text alignment. See the  align attribute definition in HTML 
-     * 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLDocument.java b/src/org/w3c/dom/html/HTMLDocument.java
deleted file mode 100644
index 21238fe..0000000
--- a/src/org/w3c/dom/html/HTMLDocument.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.NodeList;
-
-/**
- *  An <code>HTMLDocument</code> is the root of the HTML hierarchy and holds 
- * the entire content. Besides providing access to the hierarchy, it also 
- * provides some convenience methods for accessing certain sets of 
- * information from the document.
- * <p> The following properties have been deprecated in favor of the 
- * corresponding ones for the <code>BODY</code> element: alinkColor background
- *  bgColor fgColor linkColor vlinkColor In DOM Level 2, the method 
- * <code>getElementById</code> is inherited from the <code>Document</code> 
- * interface where it was moved.
- */
-public interface HTMLDocument extends Document {
-    /**
-     *  The title of a document as specified by the <code>TITLE</code> element 
-     * in the head of the document. 
-     */
-    public String getTitle();
-    public void setTitle(String title);
-
-    /**
-     *  Returns the URI of the page that linked to this page. The value is an 
-     * empty string if the user navigated to the page directly (not through a 
-     * link, but, for example, via a bookmark). 
-     */
-    public String getReferrer();
-
-    /**
-     *  The domain name of the server that served the document, or 
-     * <code>null</code> if the server cannot be identified by a domain name. 
-     */
-    public String getDomain();
-
-    /**
-     *  The complete URI of the document. 
-     */
-    public String getURL();
-
-    /**
-     *  The element that contains the content for the document. In documents 
-     * with <code>BODY</code> contents, returns the <code>BODY</code> 
-     * element. In frameset documents, this returns the outermost
-     * <code>FRAMESET</code> element. 
-     */
-    public HTMLElement getBody();
-    public void setBody(HTMLElement body);
-
-    /**
-     *  A collection of all the <code>IMG</code> elements in a document. The 
-     * behavior is limited to <code>IMG</code> elements for backwards 
-     * compatibility. 
-     */
-    public HTMLCollection getImages();
-
-    /**
-     *  A collection of all the <code>OBJECT</code> elements that include 
-     * applets and <code>APPLET</code> ( deprecated ) elements in a document. 
-     */
-    public HTMLCollection getApplets();
-
-    /**
-     *  A collection of all <code>AREA</code> elements and anchor (
-     * <code>A</code> ) elements in a document with a value for the 
-     * <code>href</code> attribute. 
-     */
-    public HTMLCollection getLinks();
-
-    /**
-     *  A collection of all the forms of a document. 
-     */
-    public HTMLCollection getForms();
-
-    /**
-     *  A collection of all the anchor (<code>A</code> ) elements in a document
-     *  with a value for the <code>name</code> attribute. Note. For reasons 
-     * of backwards compatibility, the returned set of anchors only contains 
-     * those anchors created with the <code>name</code>  attribute, not those 
-     * created with the <code>id</code> attribute. 
-     */
-    public HTMLCollection getAnchors();
-
-    /**
-     *  The cookies associated with this document. If there are none, the 
-     * value is an empty string. Otherwise, the value is a string: a 
-     * semicolon-delimited list of "name, value" pairs for all the cookies 
-     * associated with the page. For example, 
-     * <code>name=value;expires=date</code> . 
-     */
-    public String getCookie();
-    public void setCookie(String cookie);
-
-    /**
-     *  Note. This method and the ones following  allow a user to add to or 
-     * replace the structure model of a document using strings of unparsed 
-     * HTML. At the time of  writing alternate methods for providing similar 
-     * functionality for  both HTML and XML documents were being considered. 
-     * The following methods may be deprecated at some point in the future in 
-     * favor of a more general-purpose mechanism.
-     * <br> Open a document stream for writing. If a document exists in the 
-     * target, this method clears it.
-     */
-    public void open();
-
-    /**
-     *  Closes a document stream opened by <code>open()</code> and forces 
-     * rendering.
-     */
-    public void close();
-
-    /**
-     *  Write a string of text to a document stream opened by
-     * <code>open()</code> . The text is parsed into the document's structure 
-     * model.
-     * @param text  The string to be parsed into some structure in the 
-     *   document structure model.
-     */
-    public void write(String text);
-
-    /**
-     *  Write a string of text followed by a newline character to a document 
-     * stream opened by <code>open()</code> . The text is parsed into the 
-     * document's structure model.
-     * @param text  The string to be parsed into some structure in the 
-     *   document structure model.
-     */
-    public void writeln(String text);
-
-    /**
-     *  Returns the (possibly empty) collection of elements whose
-     * <code>name</code> value is given by <code>elementName</code> .
-     * @param elementName  The <code>name</code> attribute value for an 
-     *   element.
-     * @return  The matching elements.
-     */
-    public NodeList getElementsByName(String elementName);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLElement.java b/src/org/w3c/dom/html/HTMLElement.java
deleted file mode 100644
index ac82081..0000000
--- a/src/org/w3c/dom/html/HTMLElement.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-import org.w3c.dom.Element;
-
-/**
- *  All HTML element interfaces derive from this class. Elements that only 
- * expose the HTML core attributes are represented by the base 
- * <code>HTMLElement</code> interface. These elements are as follows:  HEAD 
- * special: SUB, SUP, SPAN, BDO font: TT, I, B, U, S, STRIKE, BIG, SMALL 
- * phrase: EM, STRONG, DFN, CODE, SAMP, KBD, VAR, CITE, ACRONYM, ABBR list: 
- * DD, DT NOFRAMES, NOSCRIPT ADDRESS, CENTER The <code>style</code> attribute 
- * of an HTML element is accessible through the 
- * <code>ElementCSSInlineStyle</code> interface which is defined in the  . 
- */
-public interface HTMLElement extends Element {
-    /**
-     *  The element's identifier. See the  id attribute definition in HTML 4.0.
-     */
-    public String getId();
-    public void setId(String id);
-
-    /**
-     *  The element's advisory title. See the  title attribute definition in 
-     * HTML 4.0.
-     */
-    public String getTitle();
-    public void setTitle(String title);
-
-    /**
-     *  Language code defined in RFC 1766. See the  lang attribute definition 
-     * in HTML 4.0.
-     */
-    public String getLang();
-    public void setLang(String lang);
-
-    /**
-     *  Specifies the base direction of directionally neutral text and the 
-     * directionality of tables. See the  dir attribute definition in HTML 
-     * 4.0.
-     */
-    public String getDir();
-    public void setDir(String dir);
-
-    /**
-     *  The class attribute of the element. This attribute has been renamed 
-     * due to conflicts with the "class" keyword exposed by many languages. 
-     * See the  class attribute definition in HTML 4.0.
-     */
-    public String getClassName();
-    public void setClassName(String className);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLFieldSetElement.java b/src/org/w3c/dom/html/HTMLFieldSetElement.java
deleted file mode 100644
index 3b325b4..0000000
--- a/src/org/w3c/dom/html/HTMLFieldSetElement.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Organizes form controls into logical groups. See the   FIELDSET  element 
- * definition in HTML 4.0.
- */
-public interface HTMLFieldSetElement extends HTMLElement {
-    /**
-     *  Returns the <code>FORM</code> element containing this control. Returns 
-     * <code>null</code> if this control is not within the context of a form. 
-     */
-    public HTMLFormElement getForm();
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLFontElement.java b/src/org/w3c/dom/html/HTMLFontElement.java
deleted file mode 100644
index a653ae9..0000000
--- a/src/org/w3c/dom/html/HTMLFontElement.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Local change to font. See the  FONT element definition in HTML 4.0. This 
- * element is deprecated in HTML 4.0.
- */
-public interface HTMLFontElement extends HTMLElement {
-    /**
-     *  Font color. See the  color attribute definition in HTML 4.0. This 
-     * attribute is deprecated in HTML 4.0.
-     */
-    public String getColor();
-    public void setColor(String color);
-
-    /**
-     *  Font face identifier. See the  face attribute definition in HTML 4.0. 
-     * This attribute is deprecated in HTML 4.0.
-     */
-    public String getFace();
-    public void setFace(String face);
-
-    /**
-     *  Font size. See the  size attribute definition in HTML 4.0. This 
-     * attribute is deprecated in HTML 4.0.
-     */
-    public String getSize();
-    public void setSize(String size);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLFormElement.java b/src/org/w3c/dom/html/HTMLFormElement.java
deleted file mode 100644
index aed1d90..0000000
--- a/src/org/w3c/dom/html/HTMLFormElement.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  The <code>FORM</code> element encompasses behavior similar to a collection 
- * and an element. It provides direct access to the contained input elements 
- * as well as the attributes of the form element. See the  FORM element 
- * definition in HTML 4.0.
- */
-public interface HTMLFormElement extends HTMLElement {
-    /**
-     *  Returns a collection of all control elements in the form. 
-     */
-    public HTMLCollection getElements();
-
-    /**
-     *  The number of form controls in the form.
-     */
-    public int getLength();
-
-    /**
-     *  Names the form. 
-     */
-    public String getName();
-    public void setName(String name);
-
-    /**
-     *  List of character sets supported by the server. See the  
-     * accept-charset attribute definition in HTML 4.0.
-     */
-    public String getAcceptCharset();
-    public void setAcceptCharset(String acceptCharset);
-
-    /**
-     *  Server-side form handler. See the  action attribute definition in HTML 
-     * 4.0.
-     */
-    public String getAction();
-    public void setAction(String action);
-
-    /**
-     *  The content type of the submitted form,  generally 
-     * "application/x-www-form-urlencoded".  See the  enctype attribute 
-     * definition in HTML 4.0.
-     */
-    public String getEnctype();
-    public void setEnctype(String enctype);
-
-    /**
-     *  HTTP method used to submit form. See the  method attribute definition 
-     * in HTML 4.0.
-     */
-    public String getMethod();
-    public void setMethod(String method);
-
-    /**
-     *  Frame to render the resource in. See the  target attribute definition 
-     * in HTML 4.0.
-     */
-    public String getTarget();
-    public void setTarget(String target);
-
-    /**
-     *  Submits the form. It performs the same action as a  submit button.
-     */
-    public void submit();
-
-    /**
-     *  Restores a form element's default values. It performs  the same action 
-     * as a reset button.
-     */
-    public void reset();
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLFrameElement.java b/src/org/w3c/dom/html/HTMLFrameElement.java
deleted file mode 100644
index 739cfda..0000000
--- a/src/org/w3c/dom/html/HTMLFrameElement.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Create a frame. See the  FRAME element definition in HTML 4.0.
- */
-public interface HTMLFrameElement extends HTMLElement {
-    /**
-     *  Request frame borders. See the  frameborder attribute definition in 
-     * HTML 4.0.
-     */
-    public String getFrameBorder();
-    public void setFrameBorder(String frameBorder);
-
-    /**
-     *  URI designating a long description of this image or frame. See the  
-     * longdesc attribute definition in HTML 4.0.
-     */
-    public String getLongDesc();
-    public void setLongDesc(String longDesc);
-
-    /**
-     *  Frame margin height, in pixels. See the  marginheight attribute 
-     * definition in HTML 4.0.
-     */
-    public String getMarginHeight();
-    public void setMarginHeight(String marginHeight);
-
-    /**
-     *  Frame margin width, in pixels. See the  marginwidth attribute 
-     * definition in HTML 4.0.
-     */
-    public String getMarginWidth();
-    public void setMarginWidth(String marginWidth);
-
-    /**
-     *  The frame name (object of the <code>target</code> attribute). See the  
-     * name attribute definition in HTML 4.0.
-     */
-    public String getName();
-    public void setName(String name);
-
-    /**
-     *  When true, forbid user from resizing frame. See the  noresize 
-     * attribute definition in HTML 4.0.
-     */
-    public boolean getNoResize();
-    public void setNoResize(boolean noResize);
-
-    /**
-     *  Specify whether or not the frame should have scrollbars. See the  
-     * scrolling attribute definition in HTML 4.0.
-     */
-    public String getScrolling();
-    public void setScrolling(String scrolling);
-
-    /**
-     *  A URI designating the initial frame contents. See the  src attribute 
-     * definition in HTML 4.0.
-     */
-    public String getSrc();
-    public void setSrc(String src);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLFrameSetElement.java b/src/org/w3c/dom/html/HTMLFrameSetElement.java
deleted file mode 100644
index 0679f7f..0000000
--- a/src/org/w3c/dom/html/HTMLFrameSetElement.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Create a grid of frames. See the  FRAMESET element definition in HTML 4.0.
- */
-public interface HTMLFrameSetElement extends HTMLElement {
-    /**
-     *  The number of columns of frames in the frameset. See the  cols 
-     * attribute definition in HTML 4.0.
-     */
-    public String getCols();
-    public void setCols(String cols);
-
-    /**
-     *  The number of rows of frames in the frameset. See the  rows attribute 
-     * definition in HTML 4.0.
-     */
-    public String getRows();
-    public void setRows(String rows);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLHRElement.java b/src/org/w3c/dom/html/HTMLHRElement.java
deleted file mode 100644
index d38b687..0000000
--- a/src/org/w3c/dom/html/HTMLHRElement.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Create a horizontal rule. See the  HR element definition in HTML 4.0.
- */
-public interface HTMLHRElement extends HTMLElement {
-    /**
-     *  Align the rule on the page. See the  align attribute definition in 
-     * HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-    /**
-     *  Indicates to the user agent that there should be no shading in the 
-     * rendering of this element. See the  noshade attribute definition in 
-     * HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public boolean getNoShade();
-    public void setNoShade(boolean noShade);
-
-    /**
-     *  The height of the rule. See the  size attribute definition in HTML 
-     * 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getSize();
-    public void setSize(String size);
-
-    /**
-     *  The width of the rule. See the  width attribute definition in HTML 
-     * 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getWidth();
-    public void setWidth(String width);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLHeadElement.java b/src/org/w3c/dom/html/HTMLHeadElement.java
deleted file mode 100644
index 6c5a949..0000000
--- a/src/org/w3c/dom/html/HTMLHeadElement.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Document head information. See the  HEAD element definition in HTML 4.0.
- */
-public interface HTMLHeadElement extends HTMLElement {
-    /**
-     *  URI designating a metadata profile. See the  profile attribute 
-     * definition in HTML 4.0.
-     */
-    public String getProfile();
-    public void setProfile(String profile);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLHeadingElement.java b/src/org/w3c/dom/html/HTMLHeadingElement.java
deleted file mode 100644
index 05f2391..0000000
--- a/src/org/w3c/dom/html/HTMLHeadingElement.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  For the <code>H1</code> to <code>H6</code> elements. See the  H1 element 
- * definition in HTML 4.0.
- */
-public interface HTMLHeadingElement extends HTMLElement {
-    /**
-     *  Horizontal text alignment. See the  align attribute definition in HTML 
-     * 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLHtmlElement.java b/src/org/w3c/dom/html/HTMLHtmlElement.java
deleted file mode 100644
index 568d3c3..0000000
--- a/src/org/w3c/dom/html/HTMLHtmlElement.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Root of an HTML document. See the  HTML element definition in HTML 4.0.
- */
-public interface HTMLHtmlElement extends HTMLElement {
-    /**
-     *  Version information about the document's DTD. See the  version 
-     * attribute definition in HTML 4.0. This attribute is deprecated in HTML 
-     * 4.0.
-     */
-    public String getVersion();
-    public void setVersion(String version);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLIFrameElement.java b/src/org/w3c/dom/html/HTMLIFrameElement.java
deleted file mode 100644
index 6f962e7..0000000
--- a/src/org/w3c/dom/html/HTMLIFrameElement.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Inline subwindows. See the  IFRAME element definition in HTML 4.0.
- */
-public interface HTMLIFrameElement extends HTMLElement {
-    /**
-     *  Aligns this object (vertically or horizontally)  with respect to its 
-     * surrounding text. See the  align attribute definition in HTML 4.0. 
-     * This attribute is deprecated in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-    /**
-     *  Request frame borders. See the  frameborder attribute definition in 
-     * HTML 4.0.
-     */
-    public String getFrameBorder();
-    public void setFrameBorder(String frameBorder);
-
-    /**
-     *  Frame height. See the  height attribute definition in HTML 4.0.
-     */
-    public String getHeight();
-    public void setHeight(String height);
-
-    /**
-     *  URI designating a long description of this image or frame. See the  
-     * longdesc attribute definition in HTML 4.0.
-     */
-    public String getLongDesc();
-    public void setLongDesc(String longDesc);
-
-    /**
-     *  Frame margin height, in pixels. See the  marginheight attribute 
-     * definition in HTML 4.0.
-     */
-    public String getMarginHeight();
-    public void setMarginHeight(String marginHeight);
-
-    /**
-     *  Frame margin width, in pixels. See the  marginwidth attribute 
-     * definition in HTML 4.0.
-     */
-    public String getMarginWidth();
-    public void setMarginWidth(String marginWidth);
-
-    /**
-     *  The frame name (object of the <code>target</code> attribute). See the  
-     * name attribute definition in HTML 4.0.
-     */
-    public String getName();
-    public void setName(String name);
-
-    /**
-     *  Specify whether or not the frame should have scrollbars. See the  
-     * scrolling attribute definition in HTML 4.0.
-     */
-    public String getScrolling();
-    public void setScrolling(String scrolling);
-
-    /**
-     *  A URI designating the initial frame contents. See the  src attribute 
-     * definition in HTML 4.0.
-     */
-    public String getSrc();
-    public void setSrc(String src);
-
-    /**
-     *  Frame width. See the  width attribute definition in HTML 4.0.
-     */
-    public String getWidth();
-    public void setWidth(String width);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLImageElement.java b/src/org/w3c/dom/html/HTMLImageElement.java
deleted file mode 100644
index e22fd57..0000000
--- a/src/org/w3c/dom/html/HTMLImageElement.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Embedded image. See the  IMG element definition in HTML 4.0.
- */
-public interface HTMLImageElement extends HTMLElement {
-    /**
-     *  URI designating the source of this image, for low-resolution output. 
-     */
-    public String getLowSrc();
-    public void setLowSrc(String lowSrc);
-
-    /**
-     *  The name of the element (for backwards compatibility). 
-     */
-    public String getName();
-    public void setName(String name);
-
-    /**
-     *  Aligns this object (vertically or horizontally)  with respect to its 
-     * surrounding text. See the  align attribute definition in HTML 4.0. 
-     * This attribute is deprecated in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-    /**
-     *  Alternate text for user agents not rendering the normal content of 
-     * this element. See the  alt attribute definition in HTML 4.0.
-     */
-    public String getAlt();
-    public void setAlt(String alt);
-
-    /**
-     *  Width of border around image. See the  border attribute definition in 
-     * HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getBorder();
-    public void setBorder(String border);
-
-    /**
-     *  Override height. See the  height attribute definition in HTML 4.0.
-     */
-    public String getHeight();
-    public void setHeight(String height);
-
-    /**
-     *  Horizontal space to the left and right of this image. See the  hspace 
-     * attribute definition in HTML 4.0. This attribute is deprecated in HTML 
-     * 4.0.
-     */
-    public String getHspace();
-    public void setHspace(String hspace);
-
-    /**
-     *  Use server-side image map. See the  ismap attribute definition in HTML 
-     * 4.0.
-     */
-    public boolean getIsMap();
-    public void setIsMap(boolean isMap);
-
-    /**
-     *  URI designating a long description of this image or frame. See the  
-     * longdesc attribute definition in HTML 4.0.
-     */
-    public String getLongDesc();
-    public void setLongDesc(String longDesc);
-
-    /**
-     *  URI designating the source of this image. See the  src attribute 
-     * definition in HTML 4.0.
-     */
-    public String getSrc();
-    public void setSrc(String src);
-
-    /**
-     *  Use client-side image map. See the  usemap attribute definition in 
-     * HTML 4.0.
-     */
-    public String getUseMap();
-    public void setUseMap(String useMap);
-
-    /**
-     *  Vertical space above and below this image. See the  vspace attribute 
-     * definition in HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getVspace();
-    public void setVspace(String vspace);
-
-    /**
-     *  Override width. See the  width attribute definition in HTML 4.0.
-     */
-    public String getWidth();
-    public void setWidth(String width);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLInputElement.java b/src/org/w3c/dom/html/HTMLInputElement.java
deleted file mode 100644
index 3fa20bd..0000000
--- a/src/org/w3c/dom/html/HTMLInputElement.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Form control.  Note. Depending upon the environment in which the page is 
- * being viewed, the value property may be read-only for the file upload 
- * input type. For the "password" input type, the actual value returned may 
- * be masked to prevent unauthorized use. See the  INPUT element definition 
- * in HTML 4.0.
- */
-public interface HTMLInputElement extends HTMLElement {
-    /**
-     *  When the <code>type</code> attribute of the element has the value 
-     * "Text", "File" or "Password", this represents the HTML value attribute 
-     * of the element. The value of this attribute does not change if the 
-     * contents of the corresponding form control, in an interactive user 
-     * agent, changes. Changing this attribute, however, resets the contents 
-     * of the form control. See the  value attribute definition in HTML 4.0.
-     */
-    public String getDefaultValue();
-    public void setDefaultValue(String defaultValue);
-
-    /**
-     *  When <code>type</code> has the value "Radio" or "Checkbox", this 
-     * represents the HTML checked attribute of the element. The value of 
-     * this attribute does not change if the state of the corresponding form 
-     * control, in an interactive user agent, changes. Changes to this 
-     * attribute, however, resets the state of the form control. See the  
-     * checked attribute definition in HTML 4.0.
-     */
-    public boolean getDefaultChecked();
-    public void setDefaultChecked(boolean defaultChecked);
-
-    /**
-     *  Returns the <code>FORM</code> element containing this control. Returns 
-     * <code>null</code> if this control is not within the context of a form. 
-     */
-    public HTMLFormElement getForm();
-
-    /**
-     *  A comma-separated list of content types that a server processing this 
-     * form will handle correctly. See the  accept attribute definition in 
-     * HTML 4.0.
-     */
-    public String getAccept();
-    public void setAccept(String accept);
-
-    /**
-     *  A single character access key to give access to the form control. See 
-     * the  accesskey attribute definition in HTML 4.0.
-     */
-    public String getAccessKey();
-    public void setAccessKey(String accessKey);
-
-    /**
-     *  Aligns this object (vertically or horizontally)  with respect to its 
-     * surrounding text. See the  align attribute definition in HTML 4.0. 
-     * This attribute is deprecated in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-    /**
-     *  Alternate text for user agents not rendering the normal content of 
-     * this element. See the  alt attribute definition in HTML 4.0.
-     */
-    public String getAlt();
-    public void setAlt(String alt);
-
-    /**
-     *  When the <code>type</code> attribute of the element has the value 
-     * "Radio" or "Checkbox", this represents the current state of the form 
-     * control, in an interactive user agent. Changes to this attribute 
-     * change the state of the form control, but do not change the value of 
-     * the HTML value attribute of the element.
-     */
-    public boolean getChecked();
-    public void setChecked(boolean checked);
-
-    /**
-     *  The control is unavailable in this context. See the  disabled 
-     * attribute definition in HTML 4.0.
-     */
-    public boolean getDisabled();
-    public void setDisabled(boolean disabled);
-
-    /**
-     *  Maximum number of characters for text fields, when <code>type</code> 
-     * has the value "Text" or "Password". See the  maxlength attribute 
-     * definition in HTML 4.0.
-     */
-    public int getMaxLength();
-    public void setMaxLength(int maxLength);
-
-    /**
-     *  Form control or object name when submitted with a form. See the  name 
-     * attribute definition in HTML 4.0.
-     */
-    public String getName();
-    public void setName(String name);
-
-    /**
-     *  This control is read-only. Relevant only when <code>type</code> has 
-     * the value "Text" or "Password". See the  readonly attribute definition 
-     * in HTML 4.0.
-     */
-    public boolean getReadOnly();
-    public void setReadOnly(boolean readOnly);
-
-    /**
-     *  Size information. The precise meaning is specific to each type of 
-     * field.  See the  size attribute definition in HTML 4.0.
-     */
-    public String getSize();
-    public void setSize(String size);
-
-    /**
-     *  When the <code>type</code> attribute has the value "Image", this 
-     * attribute specifies the location of the image to be used to decorate 
-     * the graphical submit button. See the  src attribute definition in HTML 
-     * 4.0.
-     */
-    public String getSrc();
-    public void setSrc(String src);
-
-    /**
-     *  Index that represents the element's position in the tabbing order. See 
-     * the  tabindex attribute definition in HTML 4.0.
-     */
-    public int getTabIndex();
-    public void setTabIndex(int tabIndex);
-
-    /**
-     *  The type of control created. See the  type attribute definition in 
-     * HTML 4.0.
-     */
-    public String getType();
-
-    /**
-     *  Use client-side image map. See the  usemap attribute definition in 
-     * HTML 4.0.
-     */
-    public String getUseMap();
-    public void setUseMap(String useMap);
-
-    /**
-     *  When the <code>type</code> attribute of the element has the value 
-     * "Text", "File" or "Password", this represents the current contents of 
-     * the corresponding form control, in an interactive user agent. Changing 
-     * this attribute changes the contents of the form control, but does not 
-     * change the value of the HTML value attribute of the element. When the 
-     * <code>type</code> attribute of the element has the value "Button", 
-     * "Hidden", "Submit", "Reset", "Image", "Checkbox" or "Radio", this 
-     * represents the HTML value attribute of the element. See the  value 
-     * attribute definition in HTML 4.0.
-     */
-    public String getValue();
-    public void setValue(String value);
-
-    /**
-     *  Removes keyboard focus from this element.
-     */
-    public void blur();
-
-    /**
-     *  Gives keyboard focus to this element.
-     */
-    public void focus();
-
-    /**
-     *  Select the contents of the text area. For <code>INPUT</code> elements 
-     * whose <code>type</code> attribute has one of the following values: 
-     * "Text", "File", or "Password".
-     */
-    public void select();
-
-    /**
-     *  Simulate a mouse-click. For <code>INPUT</code> elements whose
-     * <code>type</code> attribute has one of the following values: "Button", 
-     * "Checkbox", "Radio", "Reset", or "Submit".
-     */
-    public void click();
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLIsIndexElement.java b/src/org/w3c/dom/html/HTMLIsIndexElement.java
deleted file mode 100644
index f22bd97..0000000
--- a/src/org/w3c/dom/html/HTMLIsIndexElement.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  This element is used for single-line text input. See the  ISINDEX element 
- * definition in HTML 4.0. This element is deprecated in HTML 4.0.
- */
-public interface HTMLIsIndexElement extends HTMLElement {
-    /**
-     *  Returns the <code>FORM</code> element containing this control. Returns 
-     * <code>null</code> if this control is not within the context of a form. 
-     */
-    public HTMLFormElement getForm();
-
-    /**
-     *  The prompt message. See the  prompt attribute definition in HTML 4.0. 
-     * This attribute is deprecated in HTML 4.0.
-     */
-    public String getPrompt();
-    public void setPrompt(String prompt);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLLIElement.java b/src/org/w3c/dom/html/HTMLLIElement.java
deleted file mode 100644
index b942649..0000000
--- a/src/org/w3c/dom/html/HTMLLIElement.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  List item. See the  LI element definition in HTML 4.0.
- */
-public interface HTMLLIElement extends HTMLElement {
-    /**
-     *  List item bullet style. See the  type attribute definition in HTML 
-     * 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getType();
-    public void setType(String type);
-
-    /**
-     *  Reset sequence number when used in <code>OL</code> . See the  value 
-     * attribute definition in HTML 4.0. This attribute is deprecated in HTML 
-     * 4.0.
-     */
-    public int getValue();
-    public void setValue(int value);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLLabelElement.java b/src/org/w3c/dom/html/HTMLLabelElement.java
deleted file mode 100644
index d526dc4..0000000
--- a/src/org/w3c/dom/html/HTMLLabelElement.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Form field label text. See the  LABEL element definition in HTML 4.0.
- */
-public interface HTMLLabelElement extends HTMLElement {
-    /**
-     *  Returns the <code>FORM</code> element containing this control. Returns 
-     * <code>null</code> if this control is not within the context of a form. 
-     */
-    public HTMLFormElement getForm();
-
-    /**
-     *  A single character access key to give access to the form control. See 
-     * the  accesskey attribute definition in HTML 4.0.
-     */
-    public String getAccessKey();
-    public void setAccessKey(String accessKey);
-
-    /**
-     *  This attribute links this label with another form control by 
-     * <code>id</code> attribute. See the  for attribute definition in HTML 
-     * 4.0.
-     */
-    public String getHtmlFor();
-    public void setHtmlFor(String htmlFor);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLLegendElement.java b/src/org/w3c/dom/html/HTMLLegendElement.java
deleted file mode 100644
index 637a910..0000000
--- a/src/org/w3c/dom/html/HTMLLegendElement.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Provides a caption for a <code>FIELDSET</code> grouping.  See the  LEGEND 
- * element definition in HTML 4.0.
- */
-public interface HTMLLegendElement extends HTMLElement {
-    /**
-     *  Returns the <code>FORM</code> element containing this control. Returns 
-     * <code>null</code> if this control is not within the context of a form. 
-     */
-    public HTMLFormElement getForm();
-
-    /**
-     *  A single character access key to give access to the form control. See 
-     * the  accesskey attribute definition in HTML 4.0.
-     */
-    public String getAccessKey();
-    public void setAccessKey(String accessKey);
-
-    /**
-     *  Text alignment relative to <code>FIELDSET</code> . See the  align 
-     * attribute definition in HTML 4.0. This attribute is deprecated in HTML 
-     * 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLLinkElement.java b/src/org/w3c/dom/html/HTMLLinkElement.java
deleted file mode 100644
index f8bc1fe..0000000
--- a/src/org/w3c/dom/html/HTMLLinkElement.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  The <code>LINK</code> element specifies a link to an external resource, 
- * and defines this document's relationship to that resource (or vice versa). 
- *  See the  LINK element definition in HTML 4.0  (see also the 
- * <code>LinkStyle</code> interface in the  module).
- */
-public interface HTMLLinkElement extends HTMLElement {
-    /**
-     *  Enables/disables the link. This is currently only used for style sheet 
-     * links, and may be used to activate or deactivate style sheets. 
-     */
-    public boolean getDisabled();
-    public void setDisabled(boolean disabled);
-
-    /**
-     *  The character encoding of the resource being linked to. See the  
-     * charset attribute definition in HTML 4.0.
-     */
-    public String getCharset();
-    public void setCharset(String charset);
-
-    /**
-     *  The URI of the linked resource. See the  href attribute definition in 
-     * HTML 4.0.
-     */
-    public String getHref();
-    public void setHref(String href);
-
-    /**
-     *  Language code of the linked resource. See the  hreflang attribute 
-     * definition in HTML 4.0.
-     */
-    public String getHreflang();
-    public void setHreflang(String hreflang);
-
-    /**
-     *  Designed for use with one or more target media. See the  media 
-     * attribute definition in HTML 4.0.
-     */
-    public String getMedia();
-    public void setMedia(String media);
-
-    /**
-     *  Forward link type. See the  rel attribute definition in HTML 4.0.
-     */
-    public String getRel();
-    public void setRel(String rel);
-
-    /**
-     *  Reverse link type. See the  rev attribute definition in HTML 4.0.
-     */
-    public String getRev();
-    public void setRev(String rev);
-
-    /**
-     *  Frame to render the resource in. See the  target attribute definition 
-     * in HTML 4.0.
-     */
-    public String getTarget();
-    public void setTarget(String target);
-
-    /**
-     *  Advisory content type. See the  type attribute definition in HTML 4.0.
-     */
-    public String getType();
-    public void setType(String type);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLMapElement.java b/src/org/w3c/dom/html/HTMLMapElement.java
deleted file mode 100644
index 52b1348..0000000
--- a/src/org/w3c/dom/html/HTMLMapElement.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Client-side image map. See the  MAP element definition in HTML 4.0.
- */
-public interface HTMLMapElement extends HTMLElement {
-    /**
-     *  The list of areas defined for the image map. 
-     */
-    public HTMLCollection getAreas();
-
-    /**
-     *  Names the map (for use with <code>usemap</code> ). See the  name 
-     * attribute definition in HTML 4.0.
-     */
-    public String getName();
-    public void setName(String name);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLMenuElement.java b/src/org/w3c/dom/html/HTMLMenuElement.java
deleted file mode 100644
index 93549d6..0000000
--- a/src/org/w3c/dom/html/HTMLMenuElement.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Menu list. See the  MENU element definition in HTML 4.0. This element is 
- * deprecated in HTML 4.0.
- */
-public interface HTMLMenuElement extends HTMLElement {
-    /**
-     *  Reduce spacing between list items. See the  compact attribute 
-     * definition in HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public boolean getCompact();
-    public void setCompact(boolean compact);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLMetaElement.java b/src/org/w3c/dom/html/HTMLMetaElement.java
deleted file mode 100644
index 10aca55..0000000
--- a/src/org/w3c/dom/html/HTMLMetaElement.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  This contains generic meta-information about the document. See the  META 
- * element definition in HTML 4.0.
- */
-public interface HTMLMetaElement extends HTMLElement {
-    /**
-     *  Associated information. See the  content attribute definition in HTML 
-     * 4.0.
-     */
-    public String getContent();
-    public void setContent(String content);
-
-    /**
-     *  HTTP response header name. See the  http-equiv attribute definition in 
-     * HTML 4.0.
-     */
-    public String getHttpEquiv();
-    public void setHttpEquiv(String httpEquiv);
-
-    /**
-     *  Meta information name. See the  name attribute definition in HTML 4.0.
-     */
-    public String getName();
-    public void setName(String name);
-
-    /**
-     *  Select form of content. See the  scheme attribute definition in HTML 
-     * 4.0.
-     */
-    public String getScheme();
-    public void setScheme(String scheme);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLModElement.java b/src/org/w3c/dom/html/HTMLModElement.java
deleted file mode 100644
index fdcf87c..0000000
--- a/src/org/w3c/dom/html/HTMLModElement.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Notice of modification to part of a document. See the   INS  and  DEL  
- * element definitions in HTML 4.0. 
- */
-public interface HTMLModElement extends HTMLElement {
-    /**
-     *  A URI designating a document that describes the reason for the change. 
-     * See the  cite attribute definition in HTML 4.0.
-     */
-    public String getCite();
-    public void setCite(String cite);
-
-    /**
-     *  The date and time of the change. See the  datetime attribute definition
-     *  in HTML 4.0.
-     */
-    public String getDateTime();
-    public void setDateTime(String dateTime);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLOListElement.java b/src/org/w3c/dom/html/HTMLOListElement.java
deleted file mode 100644
index 66a39d6..0000000
--- a/src/org/w3c/dom/html/HTMLOListElement.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Ordered list. See the  OL element definition in HTML 4.0.
- */
-public interface HTMLOListElement extends HTMLElement {
-    /**
-     *  Reduce spacing between list items. See the  compact attribute 
-     * definition in HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public boolean getCompact();
-    public void setCompact(boolean compact);
-
-    /**
-     *  Starting sequence number. See the  start attribute definition in HTML 
-     * 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public int getStart();
-    public void setStart(int start);
-
-    /**
-     *  Numbering style. See the  type attribute definition in HTML 4.0. This 
-     * attribute is deprecated in HTML 4.0.
-     */
-    public String getType();
-    public void setType(String type);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLObjectElement.java b/src/org/w3c/dom/html/HTMLObjectElement.java
deleted file mode 100644
index bf60247..0000000
--- a/src/org/w3c/dom/html/HTMLObjectElement.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Generic embedded object.  Note. In principle, all properties on the object 
- * element are read-write but in some environments some properties may be 
- * read-only once the underlying object is instantiated. See the  OBJECT 
- * element definition in HTML 4.0.
- */
-public interface HTMLObjectElement extends HTMLElement {
-    /**
-     *  Returns the <code>FORM</code> element containing this control. Returns 
-     * <code>null</code> if this control is not within the context of a form. 
-     */
-    public HTMLFormElement getForm();
-
-    /**
-     *  Applet class file. See the <code>code</code> attribute for 
-     * HTMLAppletElement. 
-     */
-    public String getCode();
-    public void setCode(String code);
-
-    /**
-     *  Aligns this object (vertically or horizontally)  with respect to its 
-     * surrounding text. See the  align attribute definition in HTML 4.0. 
-     * This attribute is deprecated in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-    /**
-     *  Space-separated list of archives. See the  archive attribute definition
-     *  in HTML 4.0.
-     */
-    public String getArchive();
-    public void setArchive(String archive);
-
-    /**
-     *  Width of border around the object. See the  border attribute definition
-     *  in HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getBorder();
-    public void setBorder(String border);
-
-    /**
-     *  Base URI for <code>classid</code> , <code>data</code> , and
-     * <code>archive</code> attributes. See the  codebase attribute definition
-     *  in HTML 4.0.
-     */
-    public String getCodeBase();
-    public void setCodeBase(String codeBase);
-
-    /**
-     *  Content type for data downloaded via <code>classid</code> attribute. 
-     * See the  codetype attribute definition in HTML 4.0.
-     */
-    public String getCodeType();
-    public void setCodeType(String codeType);
-
-    /**
-     *  A URI specifying the location of the object's data.  See the  data 
-     * attribute definition in HTML 4.0.
-     */
-    public String getData();
-    public void setData(String data);
-
-    /**
-     *  Declare (for future reference), but do not instantiate, this object. 
-     * See the  declare attribute definition in HTML 4.0.
-     */
-    public boolean getDeclare();
-    public void setDeclare(boolean declare);
-
-    /**
-     *  Override height. See the  height attribute definition in HTML 4.0.
-     */
-    public String getHeight();
-    public void setHeight(String height);
-
-    /**
-     *  Horizontal space to the left and right of this image, applet, or 
-     * object. See the  hspace attribute definition in HTML 4.0. This 
-     * attribute is deprecated in HTML 4.0.
-     */
-    public String getHspace();
-    public void setHspace(String hspace);
-
-    /**
-     *  Form control or object name when submitted with a form. See the  name 
-     * attribute definition in HTML 4.0.
-     */
-    public String getName();
-    public void setName(String name);
-
-    /**
-     *  Message to render while loading the object. See the  standby attribute 
-     * definition in HTML 4.0.
-     */
-    public String getStandby();
-    public void setStandby(String standby);
-
-    /**
-     *  Index that represents the element's position in the tabbing order. See 
-     * the  tabindex attribute definition in HTML 4.0.
-     */
-    public int getTabIndex();
-    public void setTabIndex(int tabIndex);
-
-    /**
-     *  Content type for data downloaded via <code>data</code> attribute. See 
-     * the  type attribute definition in HTML 4.0.
-     */
-    public String getType();
-    public void setType(String type);
-
-    /**
-     *  Use client-side image map. See the  usemap attribute definition in 
-     * HTML 4.0.
-     */
-    public String getUseMap();
-    public void setUseMap(String useMap);
-
-    /**
-     *  Vertical space above and below this image, applet, or object. See the  
-     * vspace attribute definition in HTML 4.0. This attribute is deprecated 
-     * in HTML 4.0.
-     */
-    public String getVspace();
-    public void setVspace(String vspace);
-
-    /**
-     *  Override width. See the  width attribute definition in HTML 4.0.
-     */
-    public String getWidth();
-    public void setWidth(String width);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLOptGroupElement.java b/src/org/w3c/dom/html/HTMLOptGroupElement.java
deleted file mode 100644
index ef5a42c..0000000
--- a/src/org/w3c/dom/html/HTMLOptGroupElement.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Group options together in logical subdivisions. See the  OPTGROUP element 
- * definition in HTML 4.0.
- */
-public interface HTMLOptGroupElement extends HTMLElement {
-    /**
-     *  The control is unavailable in this context. See the  disabled 
-     * attribute definition in HTML 4.0.
-     */
-    public boolean getDisabled();
-    public void setDisabled(boolean disabled);
-
-    /**
-     *  Assigns a label to this option group. See the  label attribute 
-     * definition in HTML 4.0.
-     */
-    public String getLabel();
-    public void setLabel(String label);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLOptionElement.java b/src/org/w3c/dom/html/HTMLOptionElement.java
deleted file mode 100644
index 0047fde..0000000
--- a/src/org/w3c/dom/html/HTMLOptionElement.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  A selectable choice. See the  OPTION element definition in HTML 4.0.
- */
-public interface HTMLOptionElement extends HTMLElement {
-    /**
-     *  Returns the <code>FORM</code> element containing this control. Returns 
-     * <code>null</code> if this control is not within the context of a form. 
-     */
-    public HTMLFormElement getForm();
-
-    /**
-     *  Represents the value of the HTML selected attribute. The value of this 
-     * attribute does not change if the state of the corresponding form 
-     * control, in an interactive user agent, changes. Changing 
-     * <code>defaultSelected</code> , however, resets the state of the form 
-     * control. See the  selected attribute definition in HTML 4.0.
-     */
-    public boolean getDefaultSelected();
-    public void setDefaultSelected(boolean defaultSelected);
-
-    /**
-     *  The text contained within the option element. 
-     */
-    public String getText();
-
-    /**
-     *  The index of this <code>OPTION</code> in its parent <code>SELECT</code>
-     *  , starting from 0.
-     */
-    public int getIndex();
-
-    /**
-     *  The control is unavailable in this context. See the  disabled 
-     * attribute definition in HTML 4.0.
-     */
-    public boolean getDisabled();
-    public void setDisabled(boolean disabled);
-
-    /**
-     *  Option label for use in hierarchical menus. See the  label attribute 
-     * definition in HTML 4.0.
-     */
-    public String getLabel();
-    public void setLabel(String label);
-
-    /**
-     *  Represents the current state of the corresponding form control, in an 
-     * interactive user agent. Changing this attribute changes the state of 
-     * the form control, but does not change the value of the HTML selected 
-     * attribute of the element.
-     */
-    public boolean getSelected();
-    public void setSelected(boolean selected);
-
-    /**
-     *  The current form control value. See the  value attribute definition in 
-     * HTML 4.0.
-     */
-    public String getValue();
-    public void setValue(String value);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLParagraphElement.java b/src/org/w3c/dom/html/HTMLParagraphElement.java
deleted file mode 100644
index fe536aa..0000000
--- a/src/org/w3c/dom/html/HTMLParagraphElement.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Paragraphs. See the  P element definition in HTML 4.0.
- */
-public interface HTMLParagraphElement extends HTMLElement {
-    /**
-     *  Horizontal text alignment. See the  align attribute definition in HTML 
-     * 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLParamElement.java b/src/org/w3c/dom/html/HTMLParamElement.java
deleted file mode 100644
index e9a3c3a..0000000
--- a/src/org/w3c/dom/html/HTMLParamElement.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Parameters fed to the <code>OBJECT</code> element. See the  PARAM element 
- * definition in HTML 4.0.
- */
-public interface HTMLParamElement extends HTMLElement {
-    /**
-     *  The name of a run-time parameter. See the  name attribute definition 
-     * in HTML 4.0.
-     */
-    public String getName();
-    public void setName(String name);
-
-    /**
-     *  Content type for the <code>value</code> attribute when
-     * <code>valuetype</code> has the value "ref". See the  type attribute 
-     * definition in HTML 4.0.
-     */
-    public String getType();
-    public void setType(String type);
-
-    /**
-     *  The value of a run-time parameter. See the  value attribute definition 
-     * in HTML 4.0.
-     */
-    public String getValue();
-    public void setValue(String value);
-
-    /**
-     *  Information about the meaning of the <code>value</code> attribute 
-     * value. See the  valuetype attribute definition in HTML 4.0.
-     */
-    public String getValueType();
-    public void setValueType(String valueType);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLPreElement.java b/src/org/w3c/dom/html/HTMLPreElement.java
deleted file mode 100644
index c41e693..0000000
--- a/src/org/w3c/dom/html/HTMLPreElement.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Preformatted text. See the  PRE element definition in HTML 4.0.
- */
-public interface HTMLPreElement extends HTMLElement {
-    /**
-     *  Fixed width for content. See the  width attribute definition in HTML 
-     * 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public int getWidth();
-    public void setWidth(int width);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLQuoteElement.java b/src/org/w3c/dom/html/HTMLQuoteElement.java
deleted file mode 100644
index be1480d..0000000
--- a/src/org/w3c/dom/html/HTMLQuoteElement.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  For the <code>Q</code> and <code>BLOCKQUOTE</code> elements. See the  Q 
- * element definition in HTML 4.0.
- */
-public interface HTMLQuoteElement extends HTMLElement {
-    /**
-     *  A URI designating a source document or message. See the  cite 
-     * attribute definition in HTML 4.0.
-     */
-    public String getCite();
-    public void setCite(String cite);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLScriptElement.java b/src/org/w3c/dom/html/HTMLScriptElement.java
deleted file mode 100644
index 8222a80..0000000
--- a/src/org/w3c/dom/html/HTMLScriptElement.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Script statements. See the  SCRIPT element definition in HTML 4.0.
- */
-public interface HTMLScriptElement extends HTMLElement {
-    /**
-     *  The script content of the element. 
-     */
-    public String getText();
-    public void setText(String text);
-
-    /**
-     *  Reserved for future use. 
-     */
-    public String getHtmlFor();
-    public void setHtmlFor(String htmlFor);
-
-    /**
-     *  Reserved for future use. 
-     */
-    public String getEvent();
-    public void setEvent(String event);
-
-    /**
-     *  The character encoding of the linked resource. See the  charset 
-     * attribute definition in HTML 4.0.
-     */
-    public String getCharset();
-    public void setCharset(String charset);
-
-    /**
-     *  Indicates that the user agent can defer processing of the script.  See 
-     * the  defer attribute definition in HTML 4.0.
-     */
-    public boolean getDefer();
-    public void setDefer(boolean defer);
-
-    /**
-     *  URI designating an external script. See the  src attribute definition 
-     * in HTML 4.0.
-     */
-    public String getSrc();
-    public void setSrc(String src);
-
-    /**
-     *  The content type of the script language. See the  type attribute 
-     * definition in HTML 4.0.
-     */
-    public String getType();
-    public void setType(String type);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLSelectElement.java b/src/org/w3c/dom/html/HTMLSelectElement.java
deleted file mode 100644
index 485681d..0000000
--- a/src/org/w3c/dom/html/HTMLSelectElement.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-import org.w3c.dom.DOMException;
-
-/**
- *  The select element allows the selection of an option. The contained 
- * options can be directly accessed through the select element as a 
- * collection. See the  SELECT element definition in HTML 4.0.
- */
-public interface HTMLSelectElement extends HTMLElement {
-    /**
-     *  The type of this form control. This is the string "select-multiple" 
-     * when the multiple attribute is <code>true</code> and the string 
-     * "select-one" when <code>false</code> .
-     */
-    public String getType();
-
-    /**
-     *  The ordinal index of the selected option, starting from 0. The value 
-     * -1 is returned if no element is selected. If multiple options are 
-     * selected, the index of the first selected option is returned. 
-     */
-    public int getSelectedIndex();
-    public void setSelectedIndex(int selectedIndex);
-
-    /**
-     *  The current form control value. 
-     */
-    public String getValue();
-    public void setValue(String value);
-
-    /**
-     *  The number of options in this <code>SELECT</code> . 
-     */
-    public int getLength();
-
-    /**
-     *  Returns the <code>FORM</code> element containing this control. Returns 
-     * <code>null</code> if this control is not within the context of a form. 
-     */
-    public HTMLFormElement getForm();
-
-    /**
-     *  The collection of <code>OPTION</code> elements contained by this 
-     * element. 
-     */
-    public HTMLCollection getOptions();
-
-    /**
-     *  The control is unavailable in this context. See the  disabled 
-     * attribute definition in HTML 4.0.
-     */
-    public boolean getDisabled();
-    public void setDisabled(boolean disabled);
-
-    /**
-     *  If true, multiple <code>OPTION</code> elements may  be selected in 
-     * this <code>SELECT</code> . See the  multiple attribute definition in 
-     * HTML 4.0.
-     */
-    public boolean getMultiple();
-    public void setMultiple(boolean multiple);
-
-    /**
-     *  Form control or object name when submitted with a form. See the  name 
-     * attribute definition in HTML 4.0.
-     */
-    public String getName();
-    public void setName(String name);
-
-    /**
-     *  Number of visible rows. See the  size attribute definition in HTML 4.0.
-     */
-    public int getSize();
-    public void setSize(int size);
-
-    /**
-     *  Index that represents the element's position in the tabbing order. See 
-     * the  tabindex attribute definition in HTML 4.0.
-     */
-    public int getTabIndex();
-    public void setTabIndex(int tabIndex);
-
-    /**
-     *  Add a new element to the collection of <code>OPTION</code> elements 
-     * for this <code>SELECT</code> . This method is the equivalent of the 
-     * <code>appendChild</code> method of the <code>Node</code> interface if 
-     * the <code>before</code> parameter is <code>null</code> . It is 
-     * equivalent to the <code>insertBefore</code> method on the parent of 
-     * <code>before</code> in all other cases.
-     * @param element  The element to add.
-     * @param before  The element to insert before, or <code>null</code> for 
-     *   the tail of the list.
-     * @exception DOMException
-     *    NOT_FOUND_ERR: Raised if <code>before</code> is not a descendant of 
-     *   the <code>SELECT</code> element. 
-     */
-    public void add(HTMLElement element, 
-                    HTMLElement before)
-                    throws DOMException;
-
-    /**
-     *  Remove an element from the collection of <code>OPTION</code> elements 
-     * for this <code>SELECT</code> . Does nothing if no element has the given
-     *  index.
-     * @param index  The index of the item to remove, starting from 0.
-     */
-    public void remove(int index);
-
-    /**
-     *  Removes keyboard focus from this element.
-     */
-    public void blur();
-
-    /**
-     *  Gives keyboard focus to this element.
-     */
-    public void focus();
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLStyleElement.java b/src/org/w3c/dom/html/HTMLStyleElement.java
deleted file mode 100644
index 018d32e..0000000
--- a/src/org/w3c/dom/html/HTMLStyleElement.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Style information. See the  STYLE element definition in HTML 4.0, the  
- * module and the <code>LinkStyle</code> interface in the  module. 
- */
-public interface HTMLStyleElement extends HTMLElement {
-    /**
-     *  Enables/disables the style sheet. 
-     */
-    public boolean getDisabled();
-    public void setDisabled(boolean disabled);
-
-    /**
-     *  Designed for use with one or more target media. See the  media 
-     * attribute definition in HTML 4.0.
-     */
-    public String getMedia();
-    public void setMedia(String media);
-
-    /**
-     *  The content type pf the style sheet language. See the  type attribute 
-     * definition in HTML 4.0.
-     */
-    public String getType();
-    public void setType(String type);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLTableCaptionElement.java b/src/org/w3c/dom/html/HTMLTableCaptionElement.java
deleted file mode 100644
index b34de22..0000000
--- a/src/org/w3c/dom/html/HTMLTableCaptionElement.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Table caption See the  CAPTION element definition in HTML 4.0.
- */
-public interface HTMLTableCaptionElement extends HTMLElement {
-    /**
-     *  Caption alignment with respect to the table. See the  align attribute 
-     * definition in HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLTableCellElement.java b/src/org/w3c/dom/html/HTMLTableCellElement.java
deleted file mode 100644
index bdf8187..0000000
--- a/src/org/w3c/dom/html/HTMLTableCellElement.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  The object used to represent the <code>TH</code> and <code>TD</code> 
- * elements. See the  TD element definition in HTML 4.0.
- */
-public interface HTMLTableCellElement extends HTMLElement {
-    /**
-     *  The index of this cell in the row, starting from 0. This index is in 
-     * document tree order and not display order.
-     */
-    public int getCellIndex();
-
-    /**
-     *  Abbreviation for header cells. See the  abbr attribute definition in 
-     * HTML 4.0.
-     */
-    public String getAbbr();
-    public void setAbbr(String abbr);
-
-    /**
-     *  Horizontal alignment of data in cell. See the  align attribute 
-     * definition in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-    /**
-     *  Names group of related headers. See the  axis attribute definition in 
-     * HTML 4.0.
-     */
-    public String getAxis();
-    public void setAxis(String axis);
-
-    /**
-     *  Cell background color. See the  bgcolor attribute definition in HTML 
-     * 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getBgColor();
-    public void setBgColor(String bgColor);
-
-    /**
-     *  Alignment character for cells in a column. See the  char attribute 
-     * definition in HTML 4.0.
-     */
-    public String getCh();
-    public void setCh(String ch);
-
-    /**
-     *  Offset of alignment character. See the  charoff attribute definition 
-     * in HTML 4.0.
-     */
-    public String getChOff();
-    public void setChOff(String chOff);
-
-    /**
-     *  Number of columns spanned by cell. See the  colspan attribute 
-     * definition in HTML 4.0.
-     */
-    public int getColSpan();
-    public void setColSpan(int colSpan);
-
-    /**
-     *  List of <code>id</code> attribute values for header cells. See the  
-     * headers attribute definition in HTML 4.0.
-     */
-    public String getHeaders();
-    public void setHeaders(String headers);
-
-    /**
-     *  Cell height. See the  height attribute definition in HTML 4.0. This 
-     * attribute is deprecated in HTML 4.0.
-     */
-    public String getHeight();
-    public void setHeight(String height);
-
-    /**
-     *  Suppress word wrapping. See the  nowrap attribute definition in HTML 
-     * 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public boolean getNoWrap();
-    public void setNoWrap(boolean noWrap);
-
-    /**
-     *  Number of rows spanned by cell. See the  rowspan attribute definition 
-     * in HTML 4.0.
-     */
-    public int getRowSpan();
-    public void setRowSpan(int rowSpan);
-
-    /**
-     *  Scope covered by header cells. See the  scope attribute definition in 
-     * HTML 4.0.
-     */
-    public String getScope();
-    public void setScope(String scope);
-
-    /**
-     *  Vertical alignment of data in cell. See the  valign attribute 
-     * definition in HTML 4.0.
-     */
-    public String getVAlign();
-    public void setVAlign(String vAlign);
-
-    /**
-     *  Cell width. See the  width attribute definition in HTML 4.0. This 
-     * attribute is deprecated in HTML 4.0.
-     */
-    public String getWidth();
-    public void setWidth(String width);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLTableColElement.java b/src/org/w3c/dom/html/HTMLTableColElement.java
deleted file mode 100644
index dca9bfb..0000000
--- a/src/org/w3c/dom/html/HTMLTableColElement.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Regroups the <code>COL</code> and <code>COLGROUP</code> elements. See the  
- * COL element definition in HTML 4.0.
- */
-public interface HTMLTableColElement extends HTMLElement {
-    /**
-     *  Horizontal alignment of cell data in column. See the  align attribute 
-     * definition in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-    /**
-     *  Alignment character for cells in a column. See the  char attribute 
-     * definition in HTML 4.0.
-     */
-    public String getCh();
-    public void setCh(String ch);
-
-    /**
-     *  Offset of alignment character. See the  charoff attribute definition 
-     * in HTML 4.0.
-     */
-    public String getChOff();
-    public void setChOff(String chOff);
-
-    /**
-     *  Indicates the number of columns in a group or affected by a grouping. 
-     * See the  span attribute definition in HTML 4.0.
-     */
-    public int getSpan();
-    public void setSpan(int span);
-
-    /**
-     *  Vertical alignment of cell data in column. See the  valign attribute 
-     * definition in HTML 4.0.
-     */
-    public String getVAlign();
-    public void setVAlign(String vAlign);
-
-    /**
-     *  Default column width. See the  width attribute definition in HTML 4.0.
-     */
-    public String getWidth();
-    public void setWidth(String width);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLTableElement.java b/src/org/w3c/dom/html/HTMLTableElement.java
deleted file mode 100644
index c2b815a..0000000
--- a/src/org/w3c/dom/html/HTMLTableElement.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-import org.w3c.dom.DOMException;
-
-/**
- *  The create* and delete* methods on the table allow authors to construct 
- * and modify tables. HTML 4.0 specifies that only one of each of the 
- * <code>CAPTION</code> , <code>THEAD</code> , and <code>TFOOT</code> 
- * elements may exist in a table. Therefore, if one exists, and the 
- * createTHead() or createTFoot() method is called, the method returns the 
- * existing THead or TFoot element. See the  TABLE element definition in HTML 
- * 4.0.
- */
-public interface HTMLTableElement extends HTMLElement {
-    /**
-     *  Returns the table's <code>CAPTION</code> , or void if none exists. 
-     */
-    public HTMLTableCaptionElement getCaption();
-    public void setCaption(HTMLTableCaptionElement caption);
-
-    /**
-     *  Returns the table's <code>THEAD</code> , or <code>null</code> if none 
-     * exists. 
-     */
-    public HTMLTableSectionElement getTHead();
-    public void setTHead(HTMLTableSectionElement tHead);
-
-    /**
-     *  Returns the table's <code>TFOOT</code> , or <code>null</code> if none 
-     * exists. 
-     */
-    public HTMLTableSectionElement getTFoot();
-    public void setTFoot(HTMLTableSectionElement tFoot);
-
-    /**
-     *  Returns a collection of all the rows in the table, including all in 
-     * <code>THEAD</code> , <code>TFOOT</code> , all <code>TBODY</code> 
-     * elements. 
-     */
-    public HTMLCollection getRows();
-
-    /**
-     *  Returns a collection of the defined table bodies. 
-     */
-    public HTMLCollection getTBodies();
-
-    /**
-     *  Specifies the table's position with respect to the rest of the 
-     * document. See the  align attribute definition in HTML 4.0. This 
-     * attribute is deprecated in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-    /**
-     *  Cell background color. See the  bgcolor attribute definition in HTML 
-     * 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getBgColor();
-    public void setBgColor(String bgColor);
-
-    /**
-     *  The width of the border around the table. See the  border attribute 
-     * definition in HTML 4.0.
-     */
-    public String getBorder();
-    public void setBorder(String border);
-
-    /**
-     *  Specifies the horizontal and vertical space between cell content and 
-     * cell borders. See the  cellpadding attribute definition in HTML 4.0.
-     */
-    public String getCellPadding();
-    public void setCellPadding(String cellPadding);
-
-    /**
-     *  Specifies the horizontal and vertical separation between cells. See 
-     * the  cellspacing attribute definition in HTML 4.0.
-     */
-    public String getCellSpacing();
-    public void setCellSpacing(String cellSpacing);
-
-    /**
-     *  Specifies which external table borders to render. See the  frame 
-     * attribute definition in HTML 4.0.
-     */
-    public String getFrame();
-    public void setFrame(String frame);
-
-    /**
-     *  Specifies which internal table borders to render. See the  rules 
-     * attribute definition in HTML 4.0.
-     */
-    public String getRules();
-    public void setRules(String rules);
-
-    /**
-     *  Description about the purpose or structure of a table. See the  
-     * summary attribute definition in HTML 4.0.
-     */
-    public String getSummary();
-    public void setSummary(String summary);
-
-    /**
-     *  Specifies the desired table width. See the  width attribute definition 
-     * in HTML 4.0.
-     */
-    public String getWidth();
-    public void setWidth(String width);
-
-    /**
-     *  Create a table header row or return an existing one.
-     * @return  A new table header element (<code>THEAD</code> ).
-     */
-    public HTMLElement createTHead();
-
-    /**
-     *  Delete the header from the table, if one exists.
-     */
-    public void deleteTHead();
-
-    /**
-     *  Create a table footer row or return an existing one.
-     * @return  A footer element (<code>TFOOT</code> ).
-     */
-    public HTMLElement createTFoot();
-
-    /**
-     *  Delete the footer from the table, if one exists.
-     */
-    public void deleteTFoot();
-
-    /**
-     *  Create a new table caption object or return an existing one.
-     * @return  A <code>CAPTION</code> element.
-     */
-    public HTMLElement createCaption();
-
-    /**
-     *  Delete the table caption, if one exists.
-     */
-    public void deleteCaption();
-
-    /**
-     *  Insert a new empty row in the table. The new row is inserted 
-     * immediately before and in the same section as the current 
-     * <code>index</code> th row in the table. If <code>index</code> is equal 
-     * to the number of rows, the new row is appended. In addition, when the 
-     * table is empty the row is inserted into a <code>TBODY</code> which is 
-     * created and inserted into the table. Note. A table row cannot be empty 
-     * according to HTML 4.0 Recommendation.
-     * @param index  The row number where to insert a new row. This index 
-     *   starts from 0 and is relative to all the rows contained inside the 
-     *   table, regardless of section parentage.
-     * @return  The newly created row.
-     * @exception DOMException
-     *    INDEX_SIZE_ERR: Raised if the specified index is greater than the 
-     *   number of rows.
-     */
-    public HTMLElement insertRow(int index)
-                                 throws DOMException;
-
-    /**
-     *  Delete a table row.
-     * @param index  The index of the row to be deleted. This index starts 
-     *   from 0 and is relative to all the rows contained inside the table, 
-     *   regardless of section parentage.
-     * @exception DOMException
-     *    INDEX_SIZE_ERR: Raised if the specified index is greater than or 
-     *   equal to the number of rows.
-     */
-    public void deleteRow(int index)
-                          throws DOMException;
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLTableRowElement.java b/src/org/w3c/dom/html/HTMLTableRowElement.java
deleted file mode 100644
index fd40abd..0000000
--- a/src/org/w3c/dom/html/HTMLTableRowElement.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-import org.w3c.dom.DOMException;
-
-/**
- *  A row in a table. See the  TR element definition in HTML 4.0.
- */
-public interface HTMLTableRowElement extends HTMLElement {
-    /**
-     *  The index of this row, relative to the entire table, starting from 0. 
-     * This is in document tree order and not display order. The 
-     * <code>rowIndex</code> does not take into account sections (
-     * <code>THEAD</code> , <code>TFOOT</code> , or <code>TBODY</code> ) 
-     * within the table.
-     */
-    public int getRowIndex();
-
-    /**
-     *  The index of this row, relative to the current section (
-     * <code>THEAD</code> , <code>TFOOT</code> , or <code>TBODY</code> ), 
-     * starting from 0.
-     */
-    public int getSectionRowIndex();
-
-    /**
-     *  The collection of cells in this row. 
-     */
-    public HTMLCollection getCells();
-
-    /**
-     *  Horizontal alignment of data within cells of this row. See the  align 
-     * attribute definition in HTML 4.0.
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-    /**
-     *  Background color for rows. See the  bgcolor attribute definition in 
-     * HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public String getBgColor();
-    public void setBgColor(String bgColor);
-
-    /**
-     *  Alignment character for cells in a column. See the  char attribute 
-     * definition in HTML 4.0.
-     */
-    public String getCh();
-    public void setCh(String ch);
-
-    /**
-     *  Offset of alignment character. See the  charoff attribute definition 
-     * in HTML 4.0.
-     */
-    public String getChOff();
-    public void setChOff(String chOff);
-
-    /**
-     *  Vertical alignment of data within cells of this row. See the  valign 
-     * attribute definition in HTML 4.0.
-     */
-    public String getVAlign();
-    public void setVAlign(String vAlign);
-
-    /**
-     *  Insert an empty <code>TD</code> cell into this row. If 
-     * <code>index</code> is equal to the number of cells, the new cell is 
-     * appended
-     * @param index  The place to insert the cell, starting from 0.
-     * @return  The newly created cell.
-     * @exception DOMException
-     *    INDEX_SIZE_ERR: Raised if the specified <code>index</code> is 
-     *   greater than the number of cells.
-     */
-    public HTMLElement insertCell(int index)
-                                  throws DOMException;
-
-    /**
-     *  Delete a cell from the current row.
-     * @param index  The index of the cell to delete, starting from 0.
-     * @exception DOMException
-     *    INDEX_SIZE_ERR: Raised if the specified <code>index</code> is 
-     *   greater than or equal to the number of cells.
-     */
-    public void deleteCell(int index)
-                           throws DOMException;
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLTableSectionElement.java b/src/org/w3c/dom/html/HTMLTableSectionElement.java
deleted file mode 100644
index 90672b7..0000000
--- a/src/org/w3c/dom/html/HTMLTableSectionElement.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-import org.w3c.dom.DOMException;
-
-/**
- *  The <code>THEAD</code> , <code>TFOOT</code> , and <code>TBODY</code> 
- * elements. 
- */
-public interface HTMLTableSectionElement extends HTMLElement {
-    /**
-     *  Horizontal alignment of data in cells. See the <code>align</code> 
-     * attribute for HTMLTheadElement for details. 
-     */
-    public String getAlign();
-    public void setAlign(String align);
-
-    /**
-     *  Alignment character for cells in a column. See the  char attribute 
-     * definition in HTML 4.0.
-     */
-    public String getCh();
-    public void setCh(String ch);
-
-    /**
-     *  Offset of alignment character. See the  charoff attribute definition 
-     * in HTML 4.0.
-     */
-    public String getChOff();
-    public void setChOff(String chOff);
-
-    /**
-     *  Vertical alignment of data in cells. See the <code>valign</code> 
-     * attribute for HTMLTheadElement for details. 
-     */
-    public String getVAlign();
-    public void setVAlign(String vAlign);
-
-    /**
-     *  The collection of rows in this table section. 
-     */
-    public HTMLCollection getRows();
-
-    /**
-     *  Insert a row into this section. The new row is inserted immediately 
-     * before the current <code>index</code> th row in this section. If 
-     * <code>index</code> is equal to the number of rows in this section, the 
-     * new row is appended.
-     * @param index  The row number where to insert a new row. This index 
-     *   starts from 0 and is relative only to the rows contained inside this 
-     *   section, not all the rows in the table.
-     * @return  The newly created row.
-     * @exception DOMException
-     *    INDEX_SIZE_ERR: Raised if the specified index is greater than the 
-     *   number of rows.
-     */
-    public HTMLElement insertRow(int index)
-                                 throws DOMException;
-
-    /**
-     *  Delete a row from this section.
-     * @param index  The index of the row to be deleted. This index starts 
-     *   from 0 and is relative only to the rows contained inside this 
-     *   section, not all the rows in the table.
-     * @exception DOMException
-     *    INDEX_SIZE_ERR: Raised if the specified index is greater than or 
-     *   equal to the number of rows.
-     */
-    public void deleteRow(int index)
-                          throws DOMException;
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLTextAreaElement.java b/src/org/w3c/dom/html/HTMLTextAreaElement.java
deleted file mode 100644
index 935a727..0000000
--- a/src/org/w3c/dom/html/HTMLTextAreaElement.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Multi-line text field. See the  TEXTAREA element definition in HTML 4.0.
- */
-public interface HTMLTextAreaElement extends HTMLElement {
-    /**
-     *  Represents the contents of the element. The value of this attribute 
-     * does not change if the contents of the corresponding form control, in 
-     * an interactive user agent, changes. Changing this attribute, however, 
-     * resets the contents of the form control.
-     */
-    public String getDefaultValue();
-    public void setDefaultValue(String defaultValue);
-
-    /**
-     *  Returns the <code>FORM</code> element containing this control. Returns 
-     * <code>null</code> if this control is not within the context of a form. 
-     */
-    public HTMLFormElement getForm();
-
-    /**
-     *  A single character access key to give access to the form control. See 
-     * the  accesskey attribute definition in HTML 4.0.
-     */
-    public String getAccessKey();
-    public void setAccessKey(String accessKey);
-
-    /**
-     *  Width of control (in characters). See the  cols attribute definition 
-     * in HTML 4.0.
-     */
-    public int getCols();
-    public void setCols(int cols);
-
-    /**
-     *  The control is unavailable in this context. See the  disabled 
-     * attribute definition in HTML 4.0.
-     */
-    public boolean getDisabled();
-    public void setDisabled(boolean disabled);
-
-    /**
-     *  Form control or object name when submitted with a form. See the  name 
-     * attribute definition in HTML 4.0.
-     */
-    public String getName();
-    public void setName(String name);
-
-    /**
-     *  This control is read-only. See the  readonly attribute definition in 
-     * HTML 4.0.
-     */
-    public boolean getReadOnly();
-    public void setReadOnly(boolean readOnly);
-
-    /**
-     *  Number of text rows. See the  rows attribute definition in HTML 4.0.
-     */
-    public int getRows();
-    public void setRows(int rows);
-
-    /**
-     *  Index that represents the element's position in the tabbing order. See 
-     * the  tabindex attribute definition in HTML 4.0.
-     */
-    public int getTabIndex();
-    public void setTabIndex(int tabIndex);
-
-    /**
-     *  The type of this form control. This the string "textarea".
-     */
-    public String getType();
-
-    /**
-     *  Represents the current contents of the corresponding form control, in 
-     * an interactive user agent. Changing this attribute changes the 
-     * contents of the form control, but does not change the contents of the 
-     * element. If the entirety of the data can not fit into a single 
-     * <code>DOMString</code> , the implementation may truncate the data.
-     */
-    public String getValue();
-    public void setValue(String value);
-
-    /**
-     *  Removes keyboard focus from this element.
-     */
-    public void blur();
-
-    /**
-     *  Gives keyboard focus to this element.
-     */
-    public void focus();
-
-    /**
-     *  Select the contents of the <code>TEXTAREA</code> .
-     */
-    public void select();
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLTitleElement.java b/src/org/w3c/dom/html/HTMLTitleElement.java
deleted file mode 100644
index c99a91f..0000000
--- a/src/org/w3c/dom/html/HTMLTitleElement.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  The document title. See the  TITLE element definition in HTML 4.0.
- */
-public interface HTMLTitleElement extends HTMLElement {
-    /**
-     *  The specified title as a string. 
-     */
-    public String getText();
-    public void setText(String text);
-
-}
-
diff --git a/src/org/w3c/dom/html/HTMLUListElement.java b/src/org/w3c/dom/html/HTMLUListElement.java
deleted file mode 100644
index 27bbb1d..0000000
--- a/src/org/w3c/dom/html/HTMLUListElement.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.html;
-
-/**
- *  Unordered list. See the  UL element definition in HTML 4.0.
- */
-public interface HTMLUListElement extends HTMLElement {
-    /**
-     *  Reduce spacing between list items. See the  compact attribute 
-     * definition in HTML 4.0. This attribute is deprecated in HTML 4.0.
-     */
-    public boolean getCompact();
-    public void setCompact(boolean compact);
-
-    /**
-     *  Bullet style. See the  type attribute definition in HTML 4.0. This 
-     * attribute is deprecated in HTML 4.0.
-     */
-    public String getType();
-    public void setType(String type);
-
-}
-
diff --git a/src/org/w3c/dom/html/Makefile b/src/org/w3c/dom/html/Makefile
deleted file mode 100644
index 2382f07..0000000
--- a/src/org/w3c/dom/html/Makefile
+++ /dev/null
@@ -1,64 +0,0 @@
-# Makefile for directory ./org/w3c/dom/html
-
-TARGETS=\
-	HTMLAnchorElement.class\
-	HTMLAppletElement.class\
-	HTMLAreaElement.class\
-	HTMLBRElement.class\
-	HTMLBaseElement.class\
-	HTMLBaseFontElement.class\
-	HTMLBodyElement.class\
-	HTMLButtonElement.class\
-	HTMLCollection.class\
-	HTMLDListElement.class\
-	HTMLDOMImplementation.class\
-	HTMLDirectoryElement.class\
-	HTMLDivElement.class\
-	HTMLDocument.class\
-	HTMLElement.class\
-	HTMLFieldSetElement.class\
-	HTMLFontElement.class\
-	HTMLFormElement.class\
-	HTMLFrameElement.class\
-	HTMLFrameSetElement.class\
-	HTMLHRElement.class\
-	HTMLHeadElement.class\
-	HTMLHeadingElement.class\
-	HTMLHtmlElement.class\
-	HTMLIFrameElement.class\
-	HTMLImageElement.class\
-	HTMLInputElement.class\
-	HTMLIsIndexElement.class\
-	HTMLLIElement.class\
-	HTMLLabelElement.class\
-	HTMLLegendElement.class\
-	HTMLLinkElement.class\
-	HTMLMapElement.class\
-	HTMLMenuElement.class\
-	HTMLMetaElement.class\
-	HTMLModElement.class\
-	HTMLOListElement.class\
-	HTMLObjectElement.class\
-	HTMLOptGroupElement.class\
-	HTMLOptionElement.class\
-	HTMLParagraphElement.class\
-	HTMLParamElement.class\
-	HTMLPreElement.class\
-	HTMLQuoteElement.class\
-	HTMLScriptElement.class\
-	HTMLSelectElement.class\
-	HTMLStyleElement.class\
-	HTMLTableCaptionElement.class\
-	HTMLTableCellElement.class\
-	HTMLTableColElement.class\
-	HTMLTableElement.class\
-	HTMLTableRowElement.class\
-	HTMLTableSectionElement.class\
-	HTMLTextAreaElement.class\
-	HTMLTitleElement.class\
-	HTMLUListElement.class
-
-DIRS = 
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/w3c/dom/range/DocumentRange.java b/src/org/w3c/dom/range/DocumentRange.java
deleted file mode 100644
index 150fc39..0000000
--- a/src/org/w3c/dom/range/DocumentRange.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.range;
-
-/**
- * @since DOM Level 2
- */
-public interface DocumentRange {
-    /**
-     *  This interface can be obtained from the object implementing the 
-     * <code>Document</code> interface using binding-specific casting methods.
-     * @return  The initial state of the range returned from this  method is 
-     *   such that both of its boundary-points are positioned at the 
-     *   beginning  of the corresponding  Document, before any content. The 
-     *   range returned can only be used to select content associated with 
-     *   this Document, or with DocumentFragments and Attrs for which this 
-     *   Document is the <code>ownerDocument</code> .
-     */
-    public Range createRange();
-
-}
-
diff --git a/src/org/w3c/dom/range/Makefile b/src/org/w3c/dom/range/Makefile
deleted file mode 100644
index 06ddd33..0000000
--- a/src/org/w3c/dom/range/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Makefile for directory ./org/w3c/dom/traversal
-
-TARGETS=\
-     DocumentRange.class\
-     Range.class\
-     RangeException.class
-
-DIRS =
-
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/w3c/dom/range/Range.java b/src/org/w3c/dom/range/Range.java
deleted file mode 100644
index 17aaa31..0000000
--- a/src/org/w3c/dom/range/Range.java
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.range;
-
-import org.w3c.dom.DOMException;
-import org.w3c.dom.DocumentFragment;
-import org.w3c.dom.Node;
-
-/**
- * @since DOM Level 2
- */
-public interface Range {
-    /**
-     *  Node within which the range begins 
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public Node getStartContainer()
-                                       throws DOMException;
-
-    /**
-     *  Offset within the starting node of the range. 
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public int getStartOffset()
-                                       throws DOMException;
-
-    /**
-     *  Node within which the range ends 
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public Node getEndContainer()
-                                       throws DOMException;
-
-    /**
-     *  Offset within the ending node of the range. 
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public int getEndOffset()
-                                       throws DOMException;
-
-    /**
-     *  TRUE if the range is collapsed 
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public boolean getCollapsed()
-                                       throws DOMException;
-
-    /**
-     *  The deepest common  ancestor container of the range's two 
-     * boundary-points.
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public Node getCommonAncestorContainer()
-                                       throws DOMException;
-
-    /**
-     *  Sets the attributes describing the start of the range. 
-     * @param refNode  The <code>refNode</code> value. This parameter must be 
-     *   different from <code>null</code> .
-     * @param offset  The <code>startOffset</code> value. 
-     * @exception RangeException
-     *    INVALID_NODE_TYPE_ERR: Raised if<code>refNode</code> or an ancestor 
-     *   of <code>refNode</code> is an Entity, Notation, or DocumentType node.
-     * @exception DOMException
-     *    INDEX_SIZE_ERR: Raised if <code>offset</code> is negative or 
-     *   greater than the number of child units in <code>refNode</code> . 
-     *   Child units are 16-bit units if <code>refNode</code> is a 
-     *   CharacterData, Comment or ProcessingInstruction node. Child units 
-     *   are Nodes in all other cases.
-     *   <br> INVALID_STATE_ERR: Raised if <code>detach()</code> has already 
-     *   been invoked on this object.
-     */
-    public void setStart(Node refNode, 
-                         int offset)
-                         throws RangeException, DOMException;
-
-    /**
-     *  Sets the attributes describing the end of a range.
-     * @param refNode  The <code>refNode</code> value. This parameter must be 
-     *   different from <code>null</code> .
-     * @param offset  The <code>endOffset</code> value. 
-     * @exception RangeException
-     *    INVALID_NODE_TYPE_ERR: Raised if<code>refNode</code> or an ancestor 
-     *   of <code>refNode</code> is an Entity, Notation, or DocumentType node.
-     * @exception DOMException
-     *    INDEX_SIZE_ERR: Raised if <code>offset</code> is negative or 
-     *   greater than the number of child units in <code>refNode</code> . 
-     *   Child units are 16-bit units if <code>refNode</code> is a 
-     *   CharacterData, Comment or ProcessingInstruction node. Child units 
-     *   are Nodes in all other cases.
-     *   <br> INVALID_STATE_ERR: Raised if <code>detach()</code> has already 
-     *   been invoked on this object.
-     */
-    public void setEnd(Node refNode, 
-                       int offset)
-                       throws RangeException, DOMException;
-
-    /**
-     *  Sets the start position to be before a node
-     * @param refNode  Range starts before <code>refNode</code> 
-     * @exception RangeException
-     *    INVALID_NODE_TYPE_ERR: Raised if an ancestor of <code>refNode</code>
-     *    is an Entity, Notation, or DocumentType node or if 
-     *   <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, 
-     *   or Notation node.
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public void setStartBefore(Node refNode)
-                               throws RangeException, DOMException;
-
-    /**
-     *  Sets the start position to be after a node
-     * @param refNode  Range starts after <code>refNode</code> 
-     * @exception RangeException
-     *    INVALID_NODE_TYPE_ERR: Raised if an ancestor of <code>refNode</code>
-     *    is an Entity, Notation, or DocumentType node or if 
-     *   <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, 
-     *   or Notation node.
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public void setStartAfter(Node refNode)
-                              throws RangeException, DOMException;
-
-    /**
-     *  Sets the end position to be before a node. 
-     * @param refNode  Range ends before <code>refNode</code> 
-     * @exception RangeException
-     *    INVALID_NODE_TYPE_ERR: Raised if an ancestor of <code>refNode</code>
-     *    is an Entity, Notation, or DocumentType node or if 
-     *   <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, 
-     *   or Notation node.
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public void setEndBefore(Node refNode)
-                             throws RangeException, DOMException;
-
-    /**
-     *  Sets the end of a range to be after a node 
-     * @param refNode  Range ends after <code>refNode</code> . 
-     * @exception RangeException
-     *    INVALID_NODE_TYPE_ERR: Raised if an ancestor of <code>refNode</code>
-     *    is an Entity, Notation or DocumentType node or if 
-     *   <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, 
-     *   or Notation node.
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public void setEndAfter(Node refNode)
-                            throws RangeException, DOMException;
-
-    /**
-     *  Collapse a range onto one of its boundary-points 
-     * @param toStart  If TRUE, collapses the Range onto its start; if FALSE, 
-     *   collapses it onto its end. 
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public void collapse(boolean toStart)
-                         throws DOMException;
-
-    /**
-     *  Select a node and its contents 
-     * @param refNode  The node to select. 
-     * @exception RangeException
-     *    INVALID_NODE_TYPE_ERR: Raised if an ancestor of <code>refNode</code>
-     *    is an Entity, Notation or DocumentType node or if 
-     *   <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, 
-     *   or Notation node.
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public void selectNode(Node refNode)
-                           throws RangeException, DOMException;
-
-    /**
-     *  Select the contents within a node 
-     * @param refNode  Node to select from 
-     * @exception RangeException
-     *    INVALID_NODE_TYPE_ERR: Raised if<code>refNode</code> or an ancestor 
-     *   of <code>refNode</code> is an Entity, Notation or DocumentType node.
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public void selectNodeContents(Node refNode)
-                                   throws RangeException, DOMException;
-
-    // CompareHow
-    public static final short START_TO_START            = 0;
-    public static final short START_TO_END              = 1;
-    public static final short END_TO_END                = 2;
-    public static final short END_TO_START              = 3;
-
-    /**
-     *  Compare the boundary-points of two ranges in a document.
-     * @param how 
-     * @param sourceRange 
-     * @return  -1, 0 or 1 depending on whether the corresponding 
-     *   boundary-point of the Range is before, equal to, or after the 
-     *   corresponding boundary-point of <code>sourceRange</code> . 
-     * @exception DOMException
-     *    WRONG_DOCUMENT_ERR: Raised if the two Ranges are not in the same 
-     *   document or document fragment.
-     *   <br> INVALID_STATE_ERR: Raised if <code>detach()</code> has already 
-     *   been invoked on this object.
-     */
-    public short compareBoundaryPoints(short how, 
-                                       Range sourceRange)
-                                       throws DOMException;
-
-    /**
-     *  Removes the contents of a range from the containing document or 
-     * document fragment without returning a reference to the removed 
-     * content.  
-     * @exception DOMException
-     *    NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the content 
-     *   of the range is read-only or any of the nodes that contain any of the
-     *    content of the range are read-only.
-     *   <br> INVALID_STATE_ERR: Raised if <code>detach()</code> has already 
-     *   been invoked on this object.
-     */
-    public void deleteContents()
-                               throws DOMException;
-
-    /**
-     *  Moves the contents of a range from the containing document or document 
-     * fragment to a new DocumentFragment. 
-     * @return  A DocumentFragment containing the extracted contents. 
-     * @exception DOMException
-     *    NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the content 
-     *   of the range is read-only or any of the nodes which contain any of 
-     *   the content of the range are read-only.
-     *   <br> HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be 
-     *   extracted into the new DocumentFragment.
-     *   <br> INVALID_STATE_ERR: Raised if <code>detach()</code> has already 
-     *   been invoked on this object.
-     */
-    public DocumentFragment extractContents()
-                                            throws DOMException;
-
-    /**
-     *  Duplicates the contents of a range 
-     * @return  A DocumentFragment containing contents equivalent to those of 
-     *   this range. 
-     * @exception DOMException
-     *    HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be 
-     *   extracted into the new DocumentFragment.
-     *   <br> INVALID_STATE_ERR: Raised if <code>detach()</code> has already 
-     *   been invoked on this object.
-     */
-    public DocumentFragment cloneContents()
-                                          throws DOMException;
-
-    /**
-     *  Inserts a node into the document or document fragment at the start of 
-     * the range. 
-     * @param newNode  The node to insert at the start of the range 
-     * @exception DOMException
-     *    NO_MODIFICATION_ALLOWED_ERR: Raised if an  ancestor container of 
-     *   the start of the range is read-only.
-     *   <br> WRONG_DOCUMENT_ERR: Raised if<code>newNode</code> and the  
-     *   container of the start of the Range were not created from the same 
-     *   document.
-     *   <br> HIERARCHY_REQUEST_ERR: Raised if the  container of the start of 
-     *   the Range is of a type that does not allow children of the type of 
-     *   <code>newNode</code> or if <code>newNode</code> is an ancestor of the
-     *    container .
-     *   <br> INVALID_STATE_ERR: Raised if <code>detach()</code> has already 
-     *   been invoked on this object.
-     * @exception RangeException
-     *    INVALID_NODE_TYPE_ERR: Raised if<code>node</code> is an Attr, 
-     *   Entity, Notation, DocumentFragment, or Document node.
-     */
-    public void insertNode(Node newNode)
-                           throws DOMException, RangeException;
-
-    /**
-     *  Reparents the contents of the range to the given node and inserts the 
-     * node at the position of the start of the range. 
-     * @param newParent  The node to surround the contents with. 
-     * @exception DOMException
-     *    NO_MODIFICATION_ALLOWED_ERR: Raised if an  ancestor container of 
-     *   either boundary-point of the range is read-only.
-     *   <br> WRONG_DOCUMENT_ERR: Raised if<code>newParent</code> and the  
-     *   container of the start of the Range were not created from the same 
-     *   document.
-     *   <br> HIERARCHY_REQUEST_ERR: Raised if the  container of the start of 
-     *   the Range is of a type that does not allow children of the type of 
-     *   <code>newParent</code> or if <code>newParent</code> is an ancestor 
-     *   of the container or if <code>node</code> would end up with a child 
-     *   node of a type not allowed by the type of <code>node</code> .
-     *   <br> INVALID_STATE_ERR: Raised if <code>detach()</code> has already 
-     *   been invoked on this object.
-     * @exception RangeException
-     *    BAD_BOUNDARYPOINTS_ERR: Raised if the range  partially selects a 
-     *   non-text node.
-     *   <br> INVALID_NODE_TYPE_ERR: Raised if<code>node</code> is an Attr, 
-     *   Entity, DocumentType, Notation, Document, or DocumentFragment node.
-     */
-    public void surroundContents(Node newParent)
-                                 throws DOMException, RangeException;
-
-    /**
-     *  Produces a new range whose boundary-points are equal to the 
-     * boundary-points of the range. 
-     * @return  The duplicated range. 
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public Range cloneRange()
-                            throws DOMException;
-
-    /**
-     *  Returns the contents of a range as a string. 
-     * @return  The contents of the range.
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public String toString()
-                           throws DOMException;
-
-    /**
-     *  Called to indicate that the range is no  longer in use and that the 
-     * implementation may relinquish any resources associated with this 
-     * range. Subsequent calls to any methods or attribute getters on this 
-     * range will result in a <code>DOMException</code> being thrown with an 
-     * error code of  <code>INVALID_STATE_ERR</code> .
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if <code>detach()</code> has already been 
-     *   invoked on this object.
-     */
-    public void detach()
-                       throws DOMException;
-
-}
-
diff --git a/src/org/w3c/dom/range/RangeException.java b/src/org/w3c/dom/range/RangeException.java
deleted file mode 100644
index 005af70..0000000
--- a/src/org/w3c/dom/range/RangeException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.range;
-
-/**
- *  Range operations may throw a <code>RangeException</code> as specified in 
- * their method descriptions.
- */
-public class RangeException extends RuntimeException {
-    public RangeException(short code, String message) {
-       super(message);
-       this.code = code;
-    }
-    public short   code;
-    // RangeExceptionCode
-    public static final short BAD_BOUNDARYPOINTS_ERR    = 1;
-    public static final short INVALID_NODE_TYPE_ERR     = 2;
-
-}
-
diff --git a/src/org/w3c/dom/traversal/DocumentTraversal.java b/src/org/w3c/dom/traversal/DocumentTraversal.java
deleted file mode 100644
index 9fd6161..0000000
--- a/src/org/w3c/dom/traversal/DocumentTraversal.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.traversal;
-
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Node;
-
-/**
- * <code>DocumentTraversal</code> contains methods that create iterators and 
- * tree-walkers to traverse a node and its children in document order (depth 
- * first, pre-order traversal, which is equivalent to the order in which the 
- * start tags occur in the text representation of the document).
- * @since DOM Level 2
- */
-public interface DocumentTraversal {
-    /**
-     *  Create a new NodeIterator over the subtree rooted at the specified 
-     * node.
-     * @param root  The node which will be iterated together with its 
-     *   children. The iterator is initially positioned just before this 
-     *   node. The whatToShow flags and the filter, if any, are not 
-     *   considered when setting this position.
-     * @param whatToShow  This flag specifies which node types may appear in 
-     *   the logical view of the tree presented by the iterator. See the 
-     *   description of iterator for the set of possible values. These flags 
-     *   can be combined using <code>OR</code> .
-     * @param filter  The Filter to be used with this TreeWalker, or null to 
-     *   indicate no filter.
-     * @param entityReferenceExpansion  The value of this flag determines 
-     *   whether entity reference nodes are expanded.
-     * @return  The newly created <code>NodeIterator</code> .
-     */
-    public NodeIterator createNodeIterator(Node root, 
-                                           int whatToShow, 
-                                           NodeFilter filter, 
-                                           boolean entityReferenceExpansion);
-
-    /**
-     *  Create a new TreeWalker over the subtree rooted at the specified node.
-     * @param root  The node which will serve as the root for the 
-     *   <code>TreeWalker</code> . The whatToShow flags and the NodeFilter 
-     *   are not considered when setting this value; any node type will be 
-     *   accepted as the root. The currentNode of the TreeWalker is 
-     *   initialized to this node, whether or not it is visible. The root 
-     *   functions as a stopping point for traversal methods that look upward 
-     *   in the document structure, such as parentNode and nextNode. The root 
-     *   must not be null.
-     * @param whatToShow  This flag specifies which node types may appear in 
-     *   the logical view of the tree presented by the iterator. See the 
-     *   description of TreeWalker for the set of possible values. These 
-     *   flags can be combined using <code>OR</code> .
-     * @param filter  The Filter to be used with this TreeWalker, or null to 
-     *   indicate no filter.
-     * @param entityReferenceExpansion  The value of this flag determines 
-     *   whether entity reference nodes are expanded.
-     * @return  The newly created <code>TreeWalker</code> .
-     * @exception DOMException
-     *    Raises the exception NOT_SUPPORTED_ERR if the specified root node is
-     *    null.
-     */
-    public TreeWalker createTreeWalker(Node root, 
-                                       int whatToShow, 
-                                       NodeFilter filter, 
-                                       boolean entityReferenceExpansion)
-                                       throws DOMException;
-
-}
-
diff --git a/src/org/w3c/dom/traversal/Makefile b/src/org/w3c/dom/traversal/Makefile
deleted file mode 100644
index 1fa58db..0000000
--- a/src/org/w3c/dom/traversal/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Makefile for directory ./org/w3c/dom/traversal
-
-TARGETS=\
-     DocumentTraversal.class\
-     NodeFilter.class\
-     NodeIterator.class\
-     TreeWalker.class
-
-DIRS = 
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/w3c/dom/traversal/NodeFilter.java b/src/org/w3c/dom/traversal/NodeFilter.java
deleted file mode 100644
index 8b48c32..0000000
--- a/src/org/w3c/dom/traversal/NodeFilter.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.traversal;
-
-import org.w3c.dom.Node;
-
-/**
- *  Filters are objects that know how to "filter out" nodes. If a
- * <code>NodeIterator</code> or <code>TreeWalker</code> is given a filter, it 
- * applies the filter before it returns the next node. If the filter says to 
- * accept the node, the iterator returns it; otherwise, the iterator looks 
- * for the next node and pretends that the node that was rejected was not 
- * there.
- * <p> The DOM does not provide any filters. Filter is just an interface that 
- * users can implement to provide their own filters. 
- * <p> Filters do not need to know how to iterate, nor do they need to know 
- * anything about the data structure that is being iterated. This makes it 
- * very easy to write filters, since the only thing they have to know how to 
- * do is evaluate a single node. One filter may be used with a number of 
- * different kinds of iterators, encouraging code reuse. This is an 
- * ECMAScript function reference. This method returns a<code>short</code> . 
- * The parameter is of type <code>Node</code> . 
- * @since DOM Level 2
- */
-public interface NodeFilter {
-    // Constants returned by acceptNode
-    public static final short FILTER_ACCEPT             = 1;
-    public static final short FILTER_REJECT             = 2;
-    public static final short FILTER_SKIP               = 3;
-
-    // Constants for whatToShow
-    public static final int SHOW_ALL                  = 0xFFFFFFFF;
-    public static final int SHOW_ELEMENT              = 0x00000001;
-    public static final int SHOW_ATTRIBUTE            = 0x00000002;
-    public static final int SHOW_TEXT                 = 0x00000004;
-    public static final int SHOW_CDATA_SECTION        = 0x00000008;
-    public static final int SHOW_ENTITY_REFERENCE     = 0x00000010;
-    public static final int SHOW_ENTITY               = 0x00000020;
-    public static final int SHOW_PROCESSING_INSTRUCTION = 0x00000040;
-    public static final int SHOW_COMMENT              = 0x00000080;
-    public static final int SHOW_DOCUMENT             = 0x00000100;
-    public static final int SHOW_DOCUMENT_TYPE        = 0x00000200;
-    public static final int SHOW_DOCUMENT_FRAGMENT    = 0x00000400;
-    public static final int SHOW_NOTATION             = 0x00000800;
-
-    /**
-     *  Test whether a specified node is visible in the logical view of a 
-     * TreeWalker or NodeIterator. This function will be called by the 
-     * implementation of TreeWalker and NodeIterator; it is not intended to 
-     * be called directly from user code.
-     * @param n  The node to check to see if it passes the filter or not.
-     * @return  a constant to determine whether the node is accepted, 
-     *   rejected, or skipped, as defined  above .
-     */
-    public short acceptNode(Node n);
-
-}
-
diff --git a/src/org/w3c/dom/traversal/NodeIterator.java b/src/org/w3c/dom/traversal/NodeIterator.java
deleted file mode 100644
index a1e6d04..0000000
--- a/src/org/w3c/dom/traversal/NodeIterator.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.traversal;
-
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Node;
-
-/**
- *  NodeIterators are used to step through a set of nodes, e.g. the set of 
- * nodes in a NodeList, the document subtree governed by a particular node, 
- * the results of a query, or any other set of nodes. The set of nodes to be 
- * iterated is determined by the implementation of the NodeIterator. DOM 
- * Level 2 specifies a single NodeIterator implementation for document-order 
- * traversal of a document subtree. Instances of these iterators are created 
- * by calling DocumentTraversal.createNodeIterator().
- * @since DOM Level 2
- */
-public interface NodeIterator {
-    /**
-     *  The root node of the Iterator, as specified when it was created.
-     */
-    public Node getRoot();
-
-    /**
-     *  This attribute determines which node types are presented via the 
-     * iterator. The available set of constants is defined in the 
-     * <code>NodeFilter</code> interface.
-     */
-    public int getWhatToShow();
-
-    /**
-     *  The filter used to screen nodes.
-     */
-    public NodeFilter getFilter();
-
-    /**
-     *  The value of this flag determines whether the children of entity 
-     * reference nodes are visible to the iterator. If false, they will be 
-     * skipped over.
-     * <br> To produce a view of the document that has entity references 
-     * expanded and does not expose the entity reference node itself, use the 
-     * whatToShow flags to hide the entity reference node and set 
-     * expandEntityReferences to true when creating the iterator. To produce 
-     * a view of the document that has entity reference nodes but no entity 
-     * expansion, use the whatToShow flags to show the entity reference node 
-     * and set expandEntityReferences to false.
-     */
-    public boolean getExpandEntityReferences();
-
-    /**
-     *  Returns the next node in the set and advances the position of the 
-     * iterator in the set. After a NodeIterator is created, the first call 
-     * to nextNode() returns the first node in the set.
-     * @return  The next <code>Node</code> in the set being iterated over, or
-     *   <code>null</code> if there are no more members in that set.
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if this method is called after the
-     *   <code>detach</code> method was invoked.
-     */
-    public Node nextNode()
-                         throws DOMException;
-
-    /**
-     *  Returns the previous node in the set and moves the position of the 
-     * iterator backwards in the set.
-     * @return  The previous <code>Node</code> in the set being iterated over, 
-     *   or<code>null</code> if there are no more members in that set. 
-     * @exception DOMException
-     *    INVALID_STATE_ERR: Raised if this method is called after the
-     *   <code>detach</code> method was invoked.
-     */
-    public Node previousNode()
-                             throws DOMException;
-
-    /**
-     *  Detaches the iterator from the set which it iterated over, releasing 
-     * any computational resources and placing the iterator in the INVALID 
-     * state. After<code>detach</code> has been invoked, calls to 
-     * <code>nextNode</code> or<code>previousNode</code> will raise the 
-     * exception INVALID_STATE_ERR.
-     */
-    public void detach();
-
-}
-
diff --git a/src/org/w3c/dom/traversal/TreeWalker.java b/src/org/w3c/dom/traversal/TreeWalker.java
deleted file mode 100644
index 045016e..0000000
--- a/src/org/w3c/dom/traversal/TreeWalker.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2000 World Wide Web Consortium,
- * (Massachusetts Institute of Technology, Institut National de
- * Recherche en Informatique et en Automatique, Keio University). All
- * Rights Reserved. This program is distributed under the W3C's Software
- * Intellectual Property License. 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 W3C License http://www.w3.org/Consortium/Legal/ for more
- * details.
- */
-
-package org.w3c.dom.traversal;
-
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Node;
-
-/**
- * <code>TreeWalker</code> objects are used to navigate a document tree or 
- * subtree using the view of the document defined by its 
- * <code>whatToShow</code> flags and any filters that are defined for the 
- * <code>TreeWalker</code> . Any function which performs navigation using a 
- * <code>TreeWalker</code> will automatically support any view defined by a 
- * <code>TreeWalker</code> .
- * <p> Omitting nodes from the logical view of a subtree can result in a 
- * structure that is substantially different from the same subtree in the 
- * complete, unfiltered document. Nodes that are siblings in the TreeWalker 
- * view may be children of different, widely separated nodes in the original 
- * view. For instance, consider a Filter that skips all nodes except for Text 
- * nodes and the root node of a document. In the logical view that results, 
- * all text nodes will be siblings and appear as direct children of the root 
- * node, no matter how deeply nested the structure of the original document.
- * @since DOM Level 2
- */
-public interface TreeWalker {
-    /**
-     *  The root node of the TreeWalker, as specified when it was created.
-     */
-    public Node getRoot();
-
-    /**
-     *  This attribute determines which node types are presented via the 
-     * TreeWalker. These constants are defined in the <code>NodeFilter</code> 
-     * interface.
-     */
-    public int getWhatToShow();
-
-    /**
-     *  The filter used to screen nodes.
-     */
-    public NodeFilter getFilter();
-
-    /**
-     *  The value of this flag determines whether the children of entity 
-     * reference nodes are visible to the TreeWalker. If false, they will be 
-     * skipped over.
-     * <br> To produce a view of the document that has entity references 
-     * expanded and does not expose the entity reference node itself, use the 
-     * whatToShow flags to hide the entity reference node and set 
-     * expandEntityReferences to true when creating the TreeWalker. To 
-     * produce a view of the document that has entity reference nodes but no 
-     * entity expansion, use the whatToShow flags to show the entity 
-     * reference node and set expandEntityReferences to false.
-     */
-    public boolean getExpandEntityReferences();
-
-    /**
-     *  The node at which the TreeWalker is currently positioned.
-     * <br> The value must not be null. Alterations to the DOM tree may cause 
-     * the current node to no longer be accepted by the TreeWalker's 
-     * associated filter. currentNode may also be explicitly set to any node, 
-     * whether or not it is within the subtree specified by the root node or 
-     * would be accepted by the filter and whatToShow flags. Further 
-     * traversal occurs relative to currentNode even if it is not part of the 
-     * current view by applying the filters in the requested direction (not 
-     * changing currentNode where no traversal is possible). 
-     * @exception DOMException
-     *    NOT_SUPPORTED_ERR: Raised if the specified <code>currentNode</code> 
-     *   is<code>null</code> .
-     */
-    public Node getCurrentNode();
-    public void setCurrentNode(Node currentNode)
-                            throws DOMException;
-
-    /**
-     *  Moves to and returns the closest visible ancestor node of the current 
-     * node. If the search for parentNode attempts to step upward from the 
-     * TreeWalker's root node, or if it fails to find a visible ancestor 
-     * node, this method retains the current position and returns null.
-     * @return  The new parent node, or null if the current node has no parent 
-     *   in the TreeWalker's logical view.
-     */
-    public Node parentNode();
-
-    /**
-     *  Moves the <code>TreeWalker</code> to the first visible child of the 
-     * current node, and returns the new node. If the current node has no 
-     * visible children, returns <code>null</code> , and retains the current 
-     * node.
-     * @return  The new node, or <code>null</code> if the current node has no 
-     *   visible children in the TreeWalker's logical view.
-     */
-    public Node firstChild();
-
-    /**
-     *  Moves the <code>TreeWalker</code> to the last visible child of the 
-     * current node, and returns the new node. If the current node has no 
-     * visible children, returns <code>null</code> , and retains the current 
-     * node.
-     * @return  The new node, or <code>null</code> if the current node has no 
-     *   children  in the TreeWalker's logical view.
-     */
-    public Node lastChild();
-
-    /**
-     *  Moves the <code>TreeWalker</code> to the previous sibling of the 
-     * current node, and returns the new node. If the current node has no 
-     * visible previous sibling, returns <code>null</code> , and retains the 
-     * current node.
-     * @return  The new node, or <code>null</code> if the current node has no 
-     *   previous sibling in the TreeWalker's logical view.
-     */
-    public Node previousSibling();
-
-    /**
-     *  Moves the <code>TreeWalker</code> to the next sibling of the current 
-     * node, and returns the new node. If the current node has no visible 
-     * next sibling, returns <code>null</code> , and retains the current node.
-     * @return  The new node, or <code>null</code> if the current node has no 
-     *   next sibling in the TreeWalker's logical view.
-     */
-    public Node nextSibling();
-
-    /**
-     *  Moves the <code>TreeWalker</code> to the previous visible node in 
-     * document order relative to the current node, and returns the new node. 
-     * If the current node has no previous node,  or if the search for 
-     * previousNode attempts to step upward from the TreeWalker's root node, 
-     * returns <code>null</code> , and retains the current node. 
-     * @return  The new node, or <code>null</code> if the current node has no 
-     *   previous node in the TreeWalker's logical view.
-     */
-    public Node previousNode();
-
-    /**
-     *  Moves the <code>TreeWalker</code> to the next visible node in document 
-     * order relative to the current node, and returns the new node. If the 
-     * current node has no next node,  or if the search for nextNode attempts 
-     * to step upward from the TreeWalker's root node, returns 
-     * <code>null</code> , and retains the current node.
-     * @return  The new node, or <code>null</code> if the current node has no 
-     *   next node  in the TreeWalker's logical view.
-     */
-    public Node nextNode();
-
-}
-
diff --git a/src/org/xml/Makefile b/src/org/xml/Makefile
deleted file mode 100644
index aabf783..0000000
--- a/src/org/xml/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# Makefile for directory ./org/xml
-
-TARGETS=
-
-
-DIRS = sax
-
-TOP = ../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/xml/sax/AttributeList.java b/src/org/xml/sax/AttributeList.java
deleted file mode 100644
index 9336cef..0000000
--- a/src/org/xml/sax/AttributeList.java
+++ /dev/null
@@ -1,191 +0,0 @@
-// SAX Attribute List Interface.
-// No warranty; no copyright -- use this as you will.
-// $Id: AttributeList.java,v 1.4 2000/05/05 17:44:56 david Exp $
-
-package org.xml.sax;
-
-/**
- * Interface for an element's attribute specifications.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This is the original SAX1 interface for reporting an element's
- * attributes.  Unlike the new {@link org.xml.sax.Attributes Attributes}
- * interface, it does not support Namespace-related information.</p>
- *
- * <p>When an attribute list is supplied as part of a
- * {@link org.xml.sax.DocumentHandler#startElement startElement}
- * event, the list will return valid results only during the
- * scope of the event; once the event handler returns control
- * to the parser, the attribute list is invalid.  To save a
- * persistent copy of the attribute list, use the SAX1
- * {@link org.xml.sax.helpers.AttributeListImpl AttributeListImpl}
- * helper class.</p>
- *
- * <p>An attribute list includes only attributes that have been
- * specified or defaulted: #IMPLIED attributes will not be included.</p>
- *
- * <p>There are two ways for the SAX application to obtain information
- * from the AttributeList.  First, it can iterate through the entire
- * list:</p>
- *
- * <pre>
- * public void startElement (String name, AttributeList atts) {
- *   for (int i = 0; i < atts.getLength(); i++) {
- *     String name = atts.getName(i);
- *     String type = atts.getType(i);
- *     String value = atts.getValue(i);
- *     [...]
- *   }
- * }
- * </pre>
- *
- * <p>(Note that the result of getLength() will be zero if there
- * are no attributes.)
- *
- * <p>As an alternative, the application can request the value or
- * type of specific attributes:</p>
- *
- * <pre>
- * public void startElement (String name, AttributeList atts) {
- *   String identifier = atts.getValue("id");
- *   String label = atts.getValue("label");
- *   [...]
- * }
- * </pre>
- *
- * @deprecated This interface has been replaced by the SAX2
- *             {@link org.xml.sax.Attributes Attributes}
- *             interface, which includes Namespace support.
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.DocumentHandler#startElement startElement
- * @see org.xml.sax.helpers.AttributeListImpl AttributeListImpl
- */
-public interface AttributeList {
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Iteration methods.
-    ////////////////////////////////////////////////////////////////////
-    
-
-    /**
-     * Return the number of attributes in this list.
-     *
-     * <p>The SAX parser may provide attributes in any
-     * arbitrary order, regardless of the order in which they were
-     * declared or specified.  The number of attributes may be
-     * zero.</p>
-     *
-     * @return The number of attributes in the list.  
-     */
-    public abstract int getLength ();
-    
-    
-    /**
-     * Return the name of an attribute in this list (by position).
-     *
-     * <p>The names must be unique: the SAX parser shall not include the
-     * same attribute twice.  Attributes without values (those declared
-     * #IMPLIED without a value specified in the start tag) will be
-     * omitted from the list.</p>
-     *
-     * <p>If the attribute name has a namespace prefix, the prefix
-     * will still be attached.</p>
-     *
-     * @param i The index of the attribute in the list (starting at 0).
-     * @return The name of the indexed attribute, or null
-     *         if the index is out of range.
-     * @see #getLength 
-     */
-    public abstract String getName (int i);
-    
-    
-    /**
-     * Return the type of an attribute in the list (by position).
-     *
-     * <p>The attribute type is one of the strings "CDATA", "ID",
-     * "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES",
-     * or "NOTATION" (always in upper case).</p>
-     *
-     * <p>If the parser has not read a declaration for the attribute,
-     * or if the parser does not report attribute types, then it must
-     * return the value "CDATA" as stated in the XML 1.0 Recommentation
-     * (clause 3.3.3, "Attribute-Value Normalization").</p>
-     *
-     * <p>For an enumerated attribute that is not a notation, the
-     * parser will report the type as "NMTOKEN".</p>
-     *
-     * @param i The index of the attribute in the list (starting at 0).
-     * @return The attribute type as a string, or
-     *         null if the index is out of range.
-     * @see #getLength 
-     * @see #getType(java.lang.String)
-     */
-    public abstract String getType (int i);
-    
-    
-    /**
-     * Return the value of an attribute in the list (by position).
-     *
-     * <p>If the attribute value is a list of tokens (IDREFS,
-     * ENTITIES, or NMTOKENS), the tokens will be concatenated
-     * into a single string separated by whitespace.</p>
-     *
-     * @param i The index of the attribute in the list (starting at 0).
-     * @return The attribute value as a string, or
-     *         null if the index is out of range.
-     * @see #getLength
-     * @see #getValue(java.lang.String)
-     */
-    public abstract String getValue (int i);
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Lookup methods.
-    ////////////////////////////////////////////////////////////////////
-    
-    
-    /**
-     * Return the type of an attribute in the list (by name).
-     *
-     * <p>The return value is the same as the return value for
-     * getType(int).</p>
-     *
-     * <p>If the attribute name has a namespace prefix in the document,
-     * the application must include the prefix here.</p>
-     *
-     * @param name The name of the attribute.
-     * @return The attribute type as a string, or null if no
-     *         such attribute exists.
-     * @see #getType(int)
-     */
-    public abstract String getType (String name);
-    
-    
-    /**
-     * Return the value of an attribute in the list (by name).
-     *
-     * <p>The return value is the same as the return value for
-     * getValue(int).</p>
-     *
-     * <p>If the attribute name has a namespace prefix in the document,
-     * the application must include the prefix here.</p>
-     *
-     * @param i The index of the attribute in the list.
-     * @return The attribute value as a string, or null if
-     *         no such attribute exists.
-     * @see #getValue(int)
-     */
-    public abstract String getValue (String name);
-    
-}
-
-// end of AttributeList.java
diff --git a/src/org/xml/sax/Attributes.java b/src/org/xml/sax/Attributes.java
deleted file mode 100644
index a7dab85..0000000
--- a/src/org/xml/sax/Attributes.java
+++ /dev/null
@@ -1,243 +0,0 @@
-// Attributes.java - attribute list with Namespace support
-// Written by David Megginson, sax@megginson.com
-// NO WARRANTY!  This class is in the public domain.
-
-// $Id: Attributes.java,v 1.5 2000/05/05 17:45:09 david Exp $
-
-
-package org.xml.sax;
-
-
-/**
- * Interface for a list of XML attributes.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This interface allows access to a list of attributes in
- * three different ways:</p>
- *
- * <ol>
- * <li>by attribute index;</li>
- * <li>by Namespace-qualified name; or</li>
- * <li>by qualified (prefixed) name.</li>
- * </ol>
- *
- * <p>The list will not contain attributes that were declared
- * #IMPLIED but not specified in the start tag.  It will also not
- * contain attributes used as Namespace declarations (xmlns*) unless
- * the <code>http://xml.org/sax/features/namespace-prefixes</code> 
- * feature is set to <var>true</var> (it is <var>false</var> by 
- * default).</p>
- *
- * <p>If the namespace-prefixes feature (see above) is <var>false</var>, 
- * access by qualified name may not be available; if the 
- * <code>http://xml.org/sax/features/namespaces</code>
- * feature is <var>false</var>, access by Namespace-qualified names 
- * may not be available.</p>
- *
- * <p>This interface replaces the now-deprecated SAX1 {@link
- * org.xml.sax.AttributeList AttributeList} interface, which does not 
- * contain Namespace support.  In addition to Namespace support, it 
- * adds the <var>getIndex</var> methods (below).</p>
- *
- * <p>The order of attributes in the list is unspecified, and will
- * vary from implementation to implementation.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.helpers.AttributeListImpl
- */
-public interface Attributes
-{
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Indexed access.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Return the number of attributes in the list.
-     *
-     * <p>Once you know the number of attributes, you can iterate
-     * through the list.</p>
-     *
-     * @return The number of attributes in the list.
-     * @see #getURI(int)
-     * @see #getLocalName(int)
-     * @see #getQName(int)
-     * @see #getType(int)
-     * @see #getValue(int)
-     */
-    public abstract int getLength ();
-
-
-    /**
-     * Look up an attribute's Namespace URI by index.
-     *
-     * @param index The attribute index (zero-based).
-     * @return The Namespace URI, or the empty string if none
-     *         is available, or null if the index is out of
-     *         range.
-     * @see #getLength
-     */
-    public abstract String getURI (int index);
-
-
-    /**
-     * Look up an attribute's local name by index.
-     *
-     * @param index The attribute index (zero-based).
-     * @return The local name, or the empty string if Namespace
-     *         processing is not being performed, or null
-     *         if the index is out of range.
-     * @see #getLength
-     */
-    public abstract String getLocalName (int index);
-
-
-    /**
-     * Look up an attribute's XML 1.0 qualified name by index.
-     *
-     * @param index The attribute index (zero-based).
-     * @return The XML 1.0 qualified name, or the empty string
-     *         if none is available, or null if the index
-     *         is out of range.
-     * @see #getLength
-     */
-    public abstract String getQName (int index);
-
-
-    /**
-     * Look up an attribute's type by index.
-     *
-     * <p>The attribute type is one of the strings "CDATA", "ID",
-     * "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES",
-     * or "NOTATION" (always in upper case).</p>
-     *
-     * <p>If the parser has not read a declaration for the attribute,
-     * or if the parser does not report attribute types, then it must
-     * return the value "CDATA" as stated in the XML 1.0 Recommentation
-     * (clause 3.3.3, "Attribute-Value Normalization").</p>
-     *
-     * <p>For an enumerated attribute that is not a notation, the
-     * parser will report the type as "NMTOKEN".</p>
-     *
-     * @param index The attribute index (zero-based).
-     * @return The attribute's type as a string, or null if the
-     *         index is out of range.
-     * @see #getLength
-     */
-    public abstract String getType (int index);
-
-
-    /**
-     * Look up an attribute's value by index.
-     *
-     * <p>If the attribute value is a list of tokens (IDREFS,
-     * ENTITIES, or NMTOKENS), the tokens will be concatenated
-     * into a single string with each token separated by a
-     * single space.</p>
-     *
-     * @param index The attribute index (zero-based).
-     * @return The attribute's value as a string, or null if the
-     *         index is out of range.
-     * @see #getLength
-     */
-    public abstract String getValue (int index);
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Name-based query.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Look up the index of an attribute by Namespace name.
-     *
-     * @param uri The Namespace URI, or the empty string if
-     *        the name has no Namespace URI.
-     * @param localName The attribute's local name.
-     * @return The index of the attribute, or -1 if it does not
-     *         appear in the list.
-     */
-    public int getIndex (String uri, String localPart);
-
-
-    /**
-     * Look up the index of an attribute by XML 1.0 qualified name.
-     *
-     * @param qName The qualified (prefixed) name.
-     * @return The index of the attribute, or -1 if it does not
-     *         appear in the list.
-     */
-    public int getIndex (String qName);
-
-
-    /**
-     * Look up an attribute's type by Namespace name.
-     *
-     * <p>See {@link #getType(int) getType(int)} for a description
-     * of the possible types.</p>
-     *
-     * @param uri The Namespace URI, or the empty String if the
-     *        name has no Namespace URI.
-     * @param localName The local name of the attribute.
-     * @return The attribute type as a string, or null if the
-     *         attribute is not in the list or if Namespace
-     *         processing is not being performed.
-     */
-    public abstract String getType (String uri, String localName);
-
-
-    /**
-     * Look up an attribute's type by XML 1.0 qualified name.
-     *
-     * <p>See {@link #getType(int) getType(int)} for a description
-     * of the possible types.</p>
-     *
-     * @param qName The XML 1.0 qualified name.
-     * @return The attribute type as a string, or null if the
-     *         attribute is not in the list or if qualified names
-     *         are not available.
-     */
-    public abstract String getType (String qName);
-
-
-    /**
-     * Look up an attribute's value by Namespace name.
-     *
-     * <p>See {@link #getValue(int) getValue(int)} for a description
-     * of the possible values.</p>
-     *
-     * @param uri The Namespace URI, or the empty String if the
-     *        name has no Namespace URI.
-     * @param localName The local name of the attribute.
-     * @return The attribute value as a string, or null if the
-     *         attribute is not in the list.
-     */
-    public abstract String getValue (String uri, String localName);
-
-
-    /**
-     * Look up an attribute's value by XML 1.0 qualified name.
-     *
-     * <p>See {@link #getValue(int) getValue(int)} for a description
-     * of the possible values.</p>
-     *
-     * @param qName The XML 1.0 qualified name.
-     * @return The attribute value as a string, or null if the
-     *         attribute is not in the list or if qualified names
-     *         are not available.
-     */
-    public abstract String getValue (String qName);
-
-}
-
-// end of Attributes.java
diff --git a/src/org/xml/sax/ContentHandler.java b/src/org/xml/sax/ContentHandler.java
deleted file mode 100644
index 11a5281..0000000
--- a/src/org/xml/sax/ContentHandler.java
+++ /dev/null
@@ -1,374 +0,0 @@
-// ContentHandler.java - handle main document content.
-// Written by David Megginson, sax@megginson.com
-// NO WARRANTY!  This class is in the public domain.
-
-// $Id: ContentHandler.java,v 1.5 2000/05/05 17:45:39 david Exp $
-
-package org.xml.sax;
-
-
-/**
- * Receive notification of the logical content of a document.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This is the main interface that most SAX applications
- * implement: if the application needs to be informed of basic parsing 
- * events, it implements this interface and registers an instance with 
- * the SAX parser using the {@link org.xml.sax.XMLReader#setContentHandler 
- * setContentHandler} method.  The parser uses the instance to report 
- * basic document-related events like the start and end of elements 
- * and character data.</p>
- *
- * <p>The order of events in this interface is very important, and
- * mirrors the order of information in the document itself.  For
- * example, all of an element's content (character data, processing
- * instructions, and/or subelements) will appear, in order, between
- * the startElement event and the corresponding endElement event.</p>
- *
- * <p>This interface is similar to the now-deprecated SAX 1.0
- * DocumentHandler interface, but it adds support for Namespaces
- * and for reporting skipped entities (in non-validating XML
- * processors).</p>
- *
- * <p>Implementors should note that there is also a Java class
- * {@link java.net.ContentHandler ContentHandler} in the java.net
- * package; that means that it's probably a bad idea to do</p>
- *
- * <blockquote>
- * import java.net.*;
- * import org.xml.sax.*;
- * </blockquote>
- *
- * <p>In fact, "import ...*" is usually a sign of sloppy programming
- * anyway, so the user should consider this a feature rather than a
- * bug.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.XMLReader
- * @see org.xml.sax.DTDHandler
- * @see org.xml.sax.ErrorHandler
- */
-public interface ContentHandler
-{
-
-    /**
-     * Receive an object for locating the origin of SAX document events.
-     *
-     * <p>SAX parsers are strongly encouraged (though not absolutely
-     * required) to supply a locator: if it does so, it must supply
-     * the locator to the application by invoking this method before
-     * invoking any of the other methods in the ContentHandler
-     * interface.</p>
-     *
-     * <p>The locator allows the application to determine the end
-     * position of any document-related event, even if the parser is
-     * not reporting an error.  Typically, the application will
-     * use this information for reporting its own errors (such as
-     * character content that does not match an application's
-     * business rules).  The information returned by the locator
-     * is probably not sufficient for use with a search engine.</p>
-     *
-     * <p>Note that the locator will return correct information only
-     * during the invocation of the events in this interface.  The
-     * application should not attempt to use it at any other time.</p>
-     *
-     * @param locator An object that can return the location of
-     *                any SAX document event.
-     * @see org.xml.sax.Locator
-     */
-    public void setDocumentLocator (Locator locator);
-
-
-    /**
-     * Receive notification of the beginning of a document.
-     *
-     * <p>The SAX parser will invoke this method only once, before any
-     * other methods in this interface or in {@link org.xml.sax.DTDHandler
-     * DTDHandler} (except for {@link #setDocumentLocator 
-     * setDocumentLocator}).</p>
-     *
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see #endDocument
-     */
-    public void startDocument ()
-	throws SAXException;
-
-
-    /**
-     * Receive notification of the end of a document.
-     *
-     * <p>The SAX parser will invoke this method only once, and it will
-     * be the last method invoked during the parse.  The parser shall
-     * not invoke this method until it has either abandoned parsing
-     * (because of an unrecoverable error) or reached the end of
-     * input.</p>
-     *
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see #startDocument
-     */
-    public void endDocument()
-	throws SAXException;
-
-
-    /**
-     * Begin the scope of a prefix-URI Namespace mapping.
-     *
-     * <p>The information from this event is not necessary for
-     * normal Namespace processing: the SAX XML reader will 
-     * automatically replace prefixes for element and attribute
-     * names when the <code>http://xml.org/sax/features/namespaces</code>
-     * feature is <var>true</var> (the default).</p>
-     *
-     * <p>There are cases, however, when applications need to
-     * use prefixes in character data or in attribute values,
-     * where they cannot safely be expanded automatically; the
-     * start/endPrefixMapping event supplies the information
-     * to the application to expand prefixes in those contexts
-     * itself, if necessary.</p>
-     *
-     * <p>Note that start/endPrefixMapping events are not
-     * guaranteed to be properly nested relative to each-other:
-     * all startPrefixMapping events will occur before the
-     * corresponding {@link #startElement startElement} event, 
-     * and all {@link #endPrefixMapping endPrefixMapping}
-     * events will occur after the corresponding {@link #endElement
-     * endElement} event, but their order is not otherwise 
-     * guaranteed.</p>
-     *
-     * <p>There should never be start/endPrefixMapping events for the
-     * "xml" prefix, since it is predeclared and immutable.</p>
-     *
-     * @param prefix The Namespace prefix being declared.
-     * @param uri The Namespace URI the prefix is mapped to.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see #endPrefixMapping
-     * @see #startElement
-     */
-    public void startPrefixMapping (String prefix, String uri)
-	throws SAXException;
-
-
-    /**
-     * End the scope of a prefix-URI mapping.
-     *
-     * <p>See {@link #startPrefixMapping startPrefixMapping} for 
-     * details.  This event will always occur after the corresponding 
-     * {@link #endElement endElement} event, but the order of 
-     * {@link #endPrefixMapping endPrefixMapping} events is not otherwise
-     * guaranteed.</p>
-     *
-     * @param prefix The prefix that was being mapping.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see #startPrefixMapping
-     * @see #endElement
-     */
-    public void endPrefixMapping (String prefix)
-	throws SAXException;
-
-
-    /**
-     * Receive notification of the beginning of an element.
-     *
-     * <p>The Parser will invoke this method at the beginning of every
-     * element in the XML document; there will be a corresponding
-     * {@link #endElement endElement} event for every startElement event
-     * (even when the element is empty). All of the element's content will be
-     * reported, in order, before the corresponding endElement
-     * event.</p>
-     *
-     * <p>This event allows up to three name components for each
-     * element:</p>
-     *
-     * <ol>
-     * <li>the Namespace URI;</li>
-     * <li>the local name; and</li>
-     * <li>the qualified (prefixed) name.</li>
-     * </ol>
-     *
-     * <p>Any or all of these may be provided, depending on the
-     * values of the <var>http://xml.org/sax/features/namespaces</var>
-     * and the <var>http://xml.org/sax/features/namespace-prefixes</var>
-     * properties:</p>
-     *
-     * <ul>
-     * <li>the Namespace URI and local name are required when 
-     * the namespaces property is <var>true</var> (the default), and are
-     * optional when the namespaces property is <var>false</var> (if one is
-     * specified, both must be);</li>
-     * <li>the qualified name is required when the namespace-prefixes property
-     * is <var>true</var>, and is optional when the namespace-prefixes property
-     * is <var>false</var> (the default).</li>
-     * </ul>
-     *
-     * <p>Note that the attribute list provided will contain only
-     * attributes with explicit values (specified or defaulted):
-     * #IMPLIED attributes will be omitted.  The attribute list
-     * will contain attributes used for Namespace declarations
-     * (xmlns* attributes) only if the
-     * <code>http://xml.org/sax/features/namespace-prefixes</code>
-     * property is true (it is false by default, and support for a 
-     * true value is optional).</p>
-     *
-     * @param uri The Namespace URI, or the empty string if the
-     *        element has no Namespace URI or if Namespace
-     *        processing is not being performed.
-     * @param localName The local name (without prefix), or the
-     *        empty string if Namespace processing is not being
-     *        performed.
-     * @param qName The qualified name (with prefix), or the
-     *        empty string if qualified names are not available.
-     * @param atts The attributes attached to the element.  If
-     *        there are no attributes, it shall be an empty
-     *        Attributes object.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see #endElement
-     * @see org.xml.sax.Attributes
-     */
-    public void startElement (String namespaceURI, String localName,
-			      String qName, Attributes atts)
-	throws SAXException;
-
-
-    /**
-     * Receive notification of the end of an element.
-     *
-     * <p>The SAX parser will invoke this method at the end of every
-     * element in the XML document; there will be a corresponding
-     * {@link #startElement startElement} event for every endElement 
-     * event (even when the element is empty).</p>
-     *
-     * <p>For information on the names, see startElement.</p>
-     *
-     * @param uri The Namespace URI, or the empty string if the
-     *        element has no Namespace URI or if Namespace
-     *        processing is not being performed.
-     * @param localName The local name (without prefix), or the
-     *        empty string if Namespace processing is not being
-     *        performed.
-     * @param qName The qualified XML 1.0 name (with prefix), or the
-     *        empty string if qualified names are not available.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     */
-    public void endElement (String namespaceURI, String localName,
-			    String qName)
-	throws SAXException;
-
-
-    /**
-     * Receive notification of character data.
-     *
-     * <p>The Parser will call this method to report each chunk of
-     * character data.  SAX parsers may return all contiguous character
-     * data in a single chunk, or they may split it into several
-     * chunks; however, all of the characters in any single event
-     * must come from the same external entity so that the Locator
-     * provides useful information.</p>
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * <p>Note that some parsers will report whitespace in element
-     * content using the {@link #ignorableWhitespace ignorableWhitespace}
-     * method rather than this one (validating parsers <em>must</em> 
-     * do so).</p>
-     *
-     * @param ch The characters from the XML document.
-     * @param start The start position in the array.
-     * @param length The number of characters to read from the array.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see #ignorableWhitespace 
-     * @see org.xml.sax.Locator
-     */
-    public void characters (char ch[], int start, int length)
-	throws SAXException;
-
-
-    /**
-     * Receive notification of ignorable whitespace in element content.
-     *
-     * <p>Validating Parsers must use this method to report each chunk
-     * of whitespace in element content (see the W3C XML 1.0 recommendation,
-     * section 2.10): non-validating parsers may also use this method
-     * if they are capable of parsing and using content models.</p>
-     *
-     * <p>SAX parsers may return all contiguous whitespace in a single
-     * chunk, or they may split it into several chunks; however, all of
-     * the characters in any single event must come from the same
-     * external entity, so that the Locator provides useful
-     * information.</p>
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * @param ch The characters from the XML document.
-     * @param start The start position in the array.
-     * @param length The number of characters to read from the array.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see #characters
-     */
-    public void ignorableWhitespace (char ch[], int start, int length)
-	throws SAXException;
-
-
-    /**
-     * Receive notification of a processing instruction.
-     *
-     * <p>The Parser will invoke this method once for each processing
-     * instruction found: note that processing instructions may occur
-     * before or after the main document element.</p>
-     *
-     * <p>A SAX parser must never report an XML declaration (XML 1.0,
-     * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
-     * using this method.</p>
-     *
-     * @param target The processing instruction target.
-     * @param data The processing instruction data, or null if
-     *        none was supplied.  The data does not include any
-     *        whitespace separating it from the target.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     */
-    public void processingInstruction (String target, String data)
-	throws SAXException;
-
-
-    /**
-     * Receive notification of a skipped entity.
-     *
-     * <p>The Parser will invoke this method once for each entity
-     * skipped.  Non-validating processors may skip entities if they
-     * have not seen the declarations (because, for example, the
-     * entity was declared in an external DTD subset).  All processors
-     * may skip external entities, depending on the values of the
-     * <code>http://xml.org/sax/features/external-general-entities</code>
-     * and the
-     * <code>http://xml.org/sax/features/external-parameter-entities</code>
-     * properties.</p>
-     *
-     * @param name The name of the skipped entity.  If it is a 
-     *        parameter entity, the name will begin with '%', and if
-     *        it is the external DTD subset, it will be the string
-     *        "[dtd]".
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     */
-    public void skippedEntity (String name)
-	throws SAXException;
-}
-
-// end of ContentHandler.java
diff --git a/src/org/xml/sax/DTDHandler.java b/src/org/xml/sax/DTDHandler.java
deleted file mode 100644
index 8ea9481..0000000
--- a/src/org/xml/sax/DTDHandler.java
+++ /dev/null
@@ -1,108 +0,0 @@
-// SAX DTD handler.
-// No warranty; no copyright -- use this as you will.
-// $Id: DTDHandler.java,v 1.4 2000/05/05 17:46:02 david Exp $
-
-package org.xml.sax;
-
-/**
- * Receive notification of basic DTD-related events.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>If a SAX application needs information about notations and
- * unparsed entities, then the application implements this 
- * interface and registers an instance with the SAX parser using 
- * the parser's setDTDHandler method.  The parser uses the 
- * instance to report notation and unparsed entity declarations to 
- * the application.</p>
- *
- * <p>Note that this interface includes only those DTD events that
- * the XML recommendation <em>requires</em> processors to report:
- * notation and unparsed entity declarations.</p>
- *
- * <p>The SAX parser may report these events in any order, regardless
- * of the order in which the notations and unparsed entities were
- * declared; however, all DTD events must be reported after the
- * document handler's startDocument event, and before the first
- * startElement event.</p>
- *
- * <p>It is up to the application to store the information for 
- * future use (perhaps in a hash table or object tree).
- * If the application encounters attributes of type "NOTATION",
- * "ENTITY", or "ENTITIES", it can use the information that it
- * obtained through this interface to find the entity and/or
- * notation corresponding with the attribute value.</p>
- *
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.Parser#setDTDHandler
- * @see org.xml.sax.HandlerBase 
- */
-public interface DTDHandler {
-    
-    
-    /**
-     * Receive notification of a notation declaration event.
-     *
-     * <p>It is up to the application to record the notation for later
-     * reference, if necessary.</p>
-     *
-     * <p>At least one of publicId and systemId must be non-null.
-     * If a system identifier is present, and it is a URL, the SAX
-     * parser must resolve it fully before passing it to the
-     * application through this event.</p>
-     *
-     * <p>There is no guarantee that the notation declaration will be
-     * reported before any unparsed entities that use it.</p>
-     *
-     * @param name The notation name.
-     * @param publicId The notation's public identifier, or null if
-     *        none was given.
-     * @param systemId The notation's system identifier, or null if
-     *        none was given.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see #unparsedEntityDecl
-     * @see org.xml.sax.AttributeList
-     */
-    public abstract void notationDecl (String name,
-				       String publicId,
-				       String systemId)
-	throws SAXException;
-    
-    
-    /**
-     * Receive notification of an unparsed entity declaration event.
-     *
-     * <p>Note that the notation name corresponds to a notation
-     * reported by the {@link #notationDecl notationDecl} event.  
-     * It is up to the application to record the entity for later 
-     * reference, if necessary.</p>
-     *
-     * <p>If the system identifier is a URL, the parser must resolve it
-     * fully before passing it to the application.</p>
-     *
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @param name The unparsed entity's name.
-     * @param publicId The entity's public identifier, or null if none
-     *        was given.
-     * @param systemId The entity's system identifier.
-     * @param notation name The name of the associated notation.
-     * @see #notationDecl
-     * @see org.xml.sax.AttributeList
-     */
-    public abstract void unparsedEntityDecl (String name,
-					     String publicId,
-					     String systemId,
-					     String notationName)
-	throws SAXException;
-    
-}
-
-// end of DTDHandler.java
diff --git a/src/org/xml/sax/DocumentHandler.java b/src/org/xml/sax/DocumentHandler.java
deleted file mode 100644
index d937c0e..0000000
--- a/src/org/xml/sax/DocumentHandler.java
+++ /dev/null
@@ -1,230 +0,0 @@
-// SAX document handler.
-// No warranty; no copyright -- use this as you will.
-// $Id: DocumentHandler.java,v 1.4 2000/05/05 17:46:11 david Exp $
-
-package org.xml.sax;
-
-/**
- * Receive notification of general document events.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This was the main event-handling interface for SAX1; in
- * SAX2, it has been replaced by {@link org.xml.sax.ContentHandler
- * ContentHandler}, which provides Namespace support and reporting
- * of skipped entities.  This interface is included in SAX2 only
- * to support legacy SAX1 applications.</p>
- *
- * <p>The order of events in this interface is very important, and
- * mirrors the order of information in the document itself.  For
- * example, all of an element's content (character data, processing
- * instructions, and/or subelements) will appear, in order, between
- * the startElement event and the corresponding endElement event.</p>
- *
- * <p>Application writers who do not want to implement the entire
- * interface can derive a class from HandlerBase, which implements
- * the default functionality; parser writers can instantiate
- * HandlerBase to obtain a default handler.  The application can find
- * the location of any document event using the Locator interface
- * supplied by the Parser through the setDocumentLocator method.</p>
- *
- * @deprecated This interface has been replaced by the SAX2
- *             {@link org.xml.sax.ContentHandler ContentHandler}
- *             interface, which includes Namespace support.
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.Parser#setDocumentHandler
- * @see org.xml.sax.Locator
- * @see org.xml.sax.HandlerBase
- */
-public interface DocumentHandler {
-    
-    
-    /**
-     * Receive an object for locating the origin of SAX document events.
-     *
-     * <p>SAX parsers are strongly encouraged (though not absolutely
-     * required) to supply a locator: if it does so, it must supply
-     * the locator to the application by invoking this method before
-     * invoking any of the other methods in the DocumentHandler
-     * interface.</p>
-     *
-     * <p>The locator allows the application to determine the end
-     * position of any document-related event, even if the parser is
-     * not reporting an error.  Typically, the application will
-     * use this information for reporting its own errors (such as
-     * character content that does not match an application's
-     * business rules).  The information returned by the locator
-     * is probably not sufficient for use with a search engine.</p>
-     *
-     * <p>Note that the locator will return correct information only
-     * during the invocation of the events in this interface.  The
-     * application should not attempt to use it at any other time.</p>
-     *
-     * @param locator An object that can return the location of
-     *                any SAX document event.
-     * @see org.xml.sax.Locator
-     */
-    public abstract void setDocumentLocator (Locator locator);
-    
-    
-    /**
-     * Receive notification of the beginning of a document.
-     *
-     * <p>The SAX parser will invoke this method only once, before any
-     * other methods in this interface or in DTDHandler (except for
-     * setDocumentLocator).</p>
-     *
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     */
-    public abstract void startDocument ()
-	throws SAXException;
-    
-    
-    /**
-     * Receive notification of the end of a document.
-     *
-     * <p>The SAX parser will invoke this method only once, and it will
-     * be the last method invoked during the parse.  The parser shall
-     * not invoke this method until it has either abandoned parsing
-     * (because of an unrecoverable error) or reached the end of
-     * input.</p>
-     *
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     */
-    public abstract void endDocument ()
-	throws SAXException;
-    
-    
-    /**
-     * Receive notification of the beginning of an element.
-     *
-     * <p>The Parser will invoke this method at the beginning of every
-     * element in the XML document; there will be a corresponding
-     * endElement() event for every startElement() event (even when the
-     * element is empty). All of the element's content will be
-     * reported, in order, before the corresponding endElement()
-     * event.</p>
-     *
-     * <p>If the element name has a namespace prefix, the prefix will
-     * still be attached.  Note that the attribute list provided will
-     * contain only attributes with explicit values (specified or
-     * defaulted): #IMPLIED attributes will be omitted.</p>
-     *
-     * @param name The element type name.
-     * @param atts The attributes attached to the element, if any.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see #endElement
-     * @see org.xml.sax.AttributeList 
-     */
-    public abstract void startElement (String name, AttributeList atts)
-	throws SAXException;
-    
-    
-    /**
-     * Receive notification of the end of an element.
-     *
-     * <p>The SAX parser will invoke this method at the end of every
-     * element in the XML document; there will be a corresponding
-     * startElement() event for every endElement() event (even when the
-     * element is empty).</p>
-     *
-     * <p>If the element name has a namespace prefix, the prefix will
-     * still be attached to the name.</p>
-     *
-     * @param name The element type name
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     */
-    public abstract void endElement (String name)
-	throws SAXException;
-    
-    
-    /**
-     * Receive notification of character data.
-     *
-     * <p>The Parser will call this method to report each chunk of
-     * character data.  SAX parsers may return all contiguous character
-     * data in a single chunk, or they may split it into several
-     * chunks; however, all of the characters in any single event
-     * must come from the same external entity, so that the Locator
-     * provides useful information.</p>
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * <p>Note that some parsers will report whitespace using the
-     * ignorableWhitespace() method rather than this one (validating
-     * parsers must do so).</p>
-     *
-     * @param ch The characters from the XML document.
-     * @param start The start position in the array.
-     * @param length The number of characters to read from the array.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see #ignorableWhitespace 
-     * @see org.xml.sax.Locator
-     */
-    public abstract void characters (char ch[], int start, int length)
-	throws SAXException;
-    
-    
-    /**
-     * Receive notification of ignorable whitespace in element content.
-     *
-     * <p>Validating Parsers must use this method to report each chunk
-     * of ignorable whitespace (see the W3C XML 1.0 recommendation,
-     * section 2.10): non-validating parsers may also use this method
-     * if they are capable of parsing and using content models.</p>
-     *
-     * <p>SAX parsers may return all contiguous whitespace in a single
-     * chunk, or they may split it into several chunks; however, all of
-     * the characters in any single event must come from the same
-     * external entity, so that the Locator provides useful
-     * information.</p>
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * @param ch The characters from the XML document.
-     * @param start The start position in the array.
-     * @param length The number of characters to read from the array.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see #characters
-     */
-    public abstract void ignorableWhitespace (char ch[], int start, int length)
-	throws SAXException;
-    
-    
-    /**
-     * Receive notification of a processing instruction.
-     *
-     * <p>The Parser will invoke this method once for each processing
-     * instruction found: note that processing instructions may occur
-     * before or after the main document element.</p>
-     *
-     * <p>A SAX parser should never report an XML declaration (XML 1.0,
-     * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
-     * using this method.</p>
-     *
-     * @param target The processing instruction target.
-     * @param data The processing instruction data, or null if
-     *        none was supplied.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     */
-    public abstract void processingInstruction (String target, String data)
-	throws SAXException;
-    
-}
-
-// end of DocumentHandler.java
diff --git a/src/org/xml/sax/EntityResolver.java b/src/org/xml/sax/EntityResolver.java
deleted file mode 100644
index 724770f..0000000
--- a/src/org/xml/sax/EntityResolver.java
+++ /dev/null
@@ -1,110 +0,0 @@
-// SAX entity resolver.
-// No warranty; no copyright -- use this as you will.
-// $Id: EntityResolver.java,v 1.4 2000/05/05 17:46:19 david Exp $
-
-package org.xml.sax;
-
-import java.io.IOException;
-
-
-/**
- * Basic interface for resolving entities.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>If a SAX application needs to implement customized handling
- * for external entities, it must implement this interface and
- * register an instance with the SAX driver using the
- * {@link org.xml.sax.XMLReader#setEntityResolver setEntityResolver}
- * method.</p>
- *
- * <p>The XML reader will then allow the application to intercept any
- * external entities (including the external DTD subset and external
- * parameter entities, if any) before including them.</p>
- *
- * <p>Many SAX applications will not need to implement this interface,
- * but it will be especially useful for applications that build
- * XML documents from databases or other specialised input sources,
- * or for applications that use URI types other than URLs.</p>
- *
- * <p>The following resolver would provide the application
- * with a special character stream for the entity with the system
- * identifier "http://www.myhost.com/today":</p>
- *
- * <pre>
- * import org.xml.sax.EntityResolver;
- * import org.xml.sax.InputSource;
- *
- * public class MyResolver implements EntityResolver {
- *   public InputSource resolveEntity (String publicId, String systemId)
- *   {
- *     if (systemId.equals("http://www.myhost.com/today")) {
- *              // return a special input source
- *       MyReader reader = new MyReader();
- *       return new InputSource(reader);
- *     } else {
- *              // use the default behaviour
- *       return null;
- *     }
- *   }
- * }
- * </pre>
- *
- * <p>The application can also use this interface to redirect system
- * identifiers to local URIs or to look up replacements in a catalog
- * (possibly by using the public identifier).</p>
- *
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.Parser#setEntityResolver
- * @see org.xml.sax.InputSource
- */
-public interface EntityResolver {
-    
-    
-    /**
-     * Allow the application to resolve external entities.
-     *
-     * <p>The Parser will call this method before opening any external
-     * entity except the top-level document entity (including the
-     * external DTD subset, external entities referenced within the
-     * DTD, and external entities referenced within the document
-     * element): the application may request that the parser resolve
-     * the entity itself, that it use an alternative URI, or that it
-     * use an entirely different input source.</p>
-     *
-     * <p>Application writers can use this method to redirect external
-     * system identifiers to secure and/or local URIs, to look up
-     * public identifiers in a catalogue, or to read an entity from a
-     * database or other input source (including, for example, a dialog
-     * box).</p>
-     *
-     * <p>If the system identifier is a URL, the SAX parser must
-     * resolve it fully before reporting it to the application.</p>
-     *
-     * @param publicId The public identifier of the external entity
-     *        being referenced, or null if none was supplied.
-     * @param systemId The system identifier of the external entity
-     *        being referenced.
-     * @return An InputSource object describing the new input source,
-     *         or null to request that the parser open a regular
-     *         URI connection to the system identifier.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @exception java.io.IOException A Java-specific IO exception,
-     *            possibly the result of creating a new InputStream
-     *            or Reader for the InputSource.
-     * @see org.xml.sax.InputSource
-     */
-    public abstract InputSource resolveEntity (String publicId,
-					       String systemId)
-	throws SAXException, IOException;
-    
-}
-
-// end of EntityResolver.java
diff --git a/src/org/xml/sax/ErrorHandler.java b/src/org/xml/sax/ErrorHandler.java
deleted file mode 100644
index c4e4714..0000000
--- a/src/org/xml/sax/ErrorHandler.java
+++ /dev/null
@@ -1,123 +0,0 @@
-// SAX error handler.
-// No warranty; no copyright -- use this as you will.
-// $Id: ErrorHandler.java,v 1.4 2000/05/05 17:46:27 david Exp $
-
-package org.xml.sax;
-
-
-/**
- * Basic interface for SAX error handlers.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>If a SAX application needs to implement customized error
- * handling, it must implement this interface and then register an
- * instance with the XML reader using the
- * {@link org.xml.sax.XMLReader#setErrorHandler setErrorHandler}
- * method.  The parser will then report all errors and warnings
- * through this interface.</p>
- *
- * <p><strong>WARNING:</strong> If an application does <em>not</em>
- * register an ErrorHandler, XML parsing errors will go unreported
- * and bizarre behaviour may result.</p>
- *
- * <p>For XML processing errors, a SAX driver must use this interface 
- * instead of throwing an exception: it is up to the application 
- * to decide whether to throw an exception for different types of 
- * errors and warnings.  Note, however, that there is no requirement that 
- * the parser continue to provide useful information after a call to 
- * {@link #fatalError fatalError} (in other words, a SAX driver class 
- * could catch an exception and report a fatalError).</p>
- *
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.Parser#setErrorHandler
- * @see org.xml.sax.SAXParseException 
- */
-public interface ErrorHandler {
-    
-    
-    /**
-     * Receive notification of a warning.
-     *
-     * <p>SAX parsers will use this method to report conditions that
-     * are not errors or fatal errors as defined by the XML 1.0
-     * recommendation.  The default behaviour is to take no action.</p>
-     *
-     * <p>The SAX parser must continue to provide normal parsing events
-     * after invoking this method: it should still be possible for the
-     * application to process the document through to the end.</p>
-     *
-     * <p>Filters may use this method to report other, non-XML warnings
-     * as well.</p>
-     *
-     * @param exception The warning information encapsulated in a
-     *                  SAX parse exception.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.SAXParseException 
-     */
-    public abstract void warning (SAXParseException exception)
-	throws SAXException;
-    
-    
-    /**
-     * Receive notification of a recoverable error.
-     *
-     * <p>This corresponds to the definition of "error" in section 1.2
-     * of the W3C XML 1.0 Recommendation.  For example, a validating
-     * parser would use this callback to report the violation of a
-     * validity constraint.  The default behaviour is to take no
-     * action.</p>
-     *
-     * <p>The SAX parser must continue to provide normal parsing events
-     * after invoking this method: it should still be possible for the
-     * application to process the document through to the end.  If the
-     * application cannot do so, then the parser should report a fatal
-     * error even if the XML 1.0 recommendation does not require it to
-     * do so.</p>
-     *
-     * <p>Filters may use this method to report other, non-XML errors
-     * as well.</p>
-     *
-     * @param exception The error information encapsulated in a
-     *                  SAX parse exception.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.SAXParseException 
-     */
-    public abstract void error (SAXParseException exception)
-	throws SAXException;
-    
-    
-    /**
-     * Receive notification of a non-recoverable error.
-     *
-     * <p>This corresponds to the definition of "fatal error" in
-     * section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
-     * parser would use this callback to report the violation of a
-     * well-formedness constraint.</p>
-     *
-     * <p>The application must assume that the document is unusable
-     * after the parser has invoked this method, and should continue
-     * (if at all) only for the sake of collecting addition error
-     * messages: in fact, SAX parsers are free to stop reporting any
-     * other events once this method has been invoked.</p>
-     *
-     * @param exception The error information encapsulated in a
-     *                  SAX parse exception.  
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.SAXParseException
-     */
-    public abstract void fatalError (SAXParseException exception)
-	throws SAXException;
-    
-}
-
-// end of ErrorHandler.java
diff --git a/src/org/xml/sax/HandlerBase.java b/src/org/xml/sax/HandlerBase.java
deleted file mode 100644
index 575a0fa..0000000
--- a/src/org/xml/sax/HandlerBase.java
+++ /dev/null
@@ -1,368 +0,0 @@
-// SAX default handler base class.
-// No warranty; no copyright -- use this as you will.
-// $Id: HandlerBase.java,v 1.5 2000/05/05 17:46:37 david Exp $
-
-package org.xml.sax;
-
-/**
- * Default base class for handlers.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This class implements the default behaviour for four SAX1
- * interfaces: EntityResolver, DTDHandler, DocumentHandler,
- * and ErrorHandler.  It is now obsolete, but is included in SAX2 to
- * support legacy SAX1 applications.  SAX2 applications should use
- * the {@link org.xml.sax.helpers.DefaultHandler DefaultHandler}
- * class instead.</p>
- *
- * <p>Application writers can extend this class when they need to
- * implement only part of an interface; parser writers can
- * instantiate this class to provide default handlers when the
- * application has not supplied its own.</p>
- *
- * <p>Note that the use of this class is optional.</p>
- *
- * @deprecated This class works with the deprecated
- *             {@link org.xml.sax.DocumentHandler DocumentHandler}
- *             interface.  It has been replaced by the SAX2
- *             {@link org.xml.sax.helpers.DefaultHandler DefaultHandler}
- *             class.
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.EntityResolver
- * @see org.xml.sax.DTDHandler
- * @see org.xml.sax.DocumentHandler
- * @see org.xml.sax.ErrorHandler
- */
-public class HandlerBase
-    implements EntityResolver, DTDHandler, DocumentHandler, ErrorHandler
-{
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Default implementation of the EntityResolver interface.
-    ////////////////////////////////////////////////////////////////////
-    
-    /**
-     * Resolve an external entity.
-     *
-     * <p>Always return null, so that the parser will use the system
-     * identifier provided in the XML document.  This method implements
-     * the SAX default behaviour: application writers can override it
-     * in a subclass to do special translations such as catalog lookups
-     * or URI redirection.</p>
-     *
-     * @param publicId The public identifer, or null if none is
-     *                 available.
-     * @param systemId The system identifier provided in the XML 
-     *                 document.
-     * @return The new input source, or null to require the
-     *         default behaviour.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.EntityResolver#resolveEntity
-     */
-    public InputSource resolveEntity (String publicId, String systemId)
-	throws SAXException
-    {
-	return null;
-    }
-    
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Default implementation of DTDHandler interface.
-    ////////////////////////////////////////////////////////////////////
-    
-    
-    /**
-     * Receive notification of a notation declaration.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass if they wish to keep track of the notations
-     * declared in a document.</p>
-     *
-     * @param name The notation name.
-     * @param publicId The notation public identifier, or null if not
-     *                 available.
-     * @param systemId The notation system identifier.
-     * @see org.xml.sax.DTDHandler#notationDecl
-     */
-    public void notationDecl (String name, String publicId, String systemId)
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of an unparsed entity declaration.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to keep track of the unparsed entities
-     * declared in a document.</p>
-     *
-     * @param name The entity name.
-     * @param publicId The entity public identifier, or null if not
-     *                 available.
-     * @param systemId The entity system identifier.
-     * @param notationName The name of the associated notation.
-     * @see org.xml.sax.DTDHandler#unparsedEntityDecl
-     */
-    public void unparsedEntityDecl (String name, String publicId,
-				    String systemId, String notationName)
-    {
-	// no op
-    }
-    
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Default implementation of DocumentHandler interface.
-    ////////////////////////////////////////////////////////////////////
-    
-    
-    /**
-     * Receive a Locator object for document events.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass if they wish to store the locator for use
-     * with other document events.</p>
-     *
-     * @param locator A locator for all SAX document events.
-     * @see org.xml.sax.DocumentHandler#setDocumentLocator
-     * @see org.xml.sax.Locator
-     */
-    public void setDocumentLocator (Locator locator)
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of the beginning of the document.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to take specific actions at the beginning
-     * of a document (such as allocating the root node of a tree or
-     * creating an output file).</p>
-     *
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.DocumentHandler#startDocument
-     */
-    public void startDocument ()
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of the end of the document.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to take specific actions at the beginning
-     * of a document (such as finalising a tree or closing an output
-     * file).</p>
-     *
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.DocumentHandler#endDocument
-     */
-    public void endDocument ()
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of the start of an element.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to take specific actions at the start of
-     * each element (such as allocating a new tree node or writing
-     * output to a file).</p>
-     *
-     * @param name The element type name.
-     * @param attributes The specified or defaulted attributes.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.DocumentHandler#startElement
-     */
-    public void startElement (String name, AttributeList attributes)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of the end of an element.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to take specific actions at the end of
-     * each element (such as finalising a tree node or writing
-     * output to a file).</p>
-     *
-     * @param name The element type name.
-     * @param attributes The specified or defaulted attributes.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.DocumentHandler#endElement
-     */
-    public void endElement (String name)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of character data inside an element.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method to take specific actions for each chunk of character data
-     * (such as adding the data to a node or buffer, or printing it to
-     * a file).</p>
-     *
-     * @param ch The characters.
-     * @param start The start position in the character array.
-     * @param length The number of characters to use from the
-     *               character array.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.DocumentHandler#characters
-     */
-    public void characters (char ch[], int start, int length)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of ignorable whitespace in element content.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method to take specific actions for each chunk of ignorable
-     * whitespace (such as adding data to a node or buffer, or printing
-     * it to a file).</p>
-     *
-     * @param ch The whitespace characters.
-     * @param start The start position in the character array.
-     * @param length The number of characters to use from the
-     *               character array.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.DocumentHandler#ignorableWhitespace
-     */
-    public void ignorableWhitespace (char ch[], int start, int length)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of a processing instruction.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to take specific actions for each
-     * processing instruction, such as setting status variables or
-     * invoking other methods.</p>
-     *
-     * @param target The processing instruction target.
-     * @param data The processing instruction data, or null if
-     *             none is supplied.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.DocumentHandler#processingInstruction
-     */
-    public void processingInstruction (String target, String data)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Default implementation of the ErrorHandler interface.
-    ////////////////////////////////////////////////////////////////////
-    
-    
-    /**
-     * Receive notification of a parser warning.
-     *
-     * <p>The default implementation does nothing.  Application writers
-     * may override this method in a subclass to take specific actions
-     * for each warning, such as inserting the message in a log file or
-     * printing it to the console.</p>
-     *
-     * @param e The warning information encoded as an exception.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ErrorHandler#warning
-     * @see org.xml.sax.SAXParseException
-     */
-    public void warning (SAXParseException e)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of a recoverable parser error.
-     *
-     * <p>The default implementation does nothing.  Application writers
-     * may override this method in a subclass to take specific actions
-     * for each error, such as inserting the message in a log file or
-     * printing it to the console.</p>
-     *
-     * @param e The warning information encoded as an exception.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ErrorHandler#warning
-     * @see org.xml.sax.SAXParseException
-     */
-    public void error (SAXParseException e)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Report a fatal XML parsing error.
-     *
-     * <p>The default implementation throws a SAXParseException.
-     * Application writers may override this method in a subclass if
-     * they need to take specific actions for each fatal error (such as
-     * collecting all of the errors into a single report): in any case,
-     * the application must stop all regular processing when this
-     * method is invoked, since the document is no longer reliable, and
-     * the parser may no longer report parsing events.</p>
-     *
-     * @param e The error information encoded as an exception.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ErrorHandler#fatalError
-     * @see org.xml.sax.SAXParseException
-     */
-    public void fatalError (SAXParseException e)
-	throws SAXException
-    {
-	throw e;
-    }
-    
-}
-
-// end of HandlerBase.java
diff --git a/src/org/xml/sax/InputSource.java b/src/org/xml/sax/InputSource.java
deleted file mode 100644
index 574e483..0000000
--- a/src/org/xml/sax/InputSource.java
+++ /dev/null
@@ -1,321 +0,0 @@
-// SAX input source.
-// No warranty; no copyright -- use this as you will.
-// $Id: InputSource.java,v 1.5 2000/05/05 17:46:48 david Exp $
-
-package org.xml.sax;
-
-import java.io.Reader;
-import java.io.InputStream;
-
-/**
- * A single input source for an XML entity.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This class allows a SAX application to encapsulate information
- * about an input source in a single object, which may include
- * a public identifier, a system identifier, a byte stream (possibly
- * with a specified encoding), and/or a character stream.</p>
- *
- * <p>There are two places that the application will deliver this
- * input source to the parser: as the argument to the Parser.parse
- * method, or as the return value of the EntityResolver.resolveEntity
- * method.</p>
- *
- * <p>The SAX parser will use the InputSource object to determine how
- * to read XML input.  If there is a character stream available, the
- * parser will read that stream directly; if not, the parser will use
- * a byte stream, if available; if neither a character stream nor a
- * byte stream is available, the parser will attempt to open a URI
- * connection to the resource identified by the system
- * identifier.</p>
- *
- * <p>An InputSource object belongs to the application: the SAX parser
- * shall never modify it in any way (it may modify a copy if 
- * necessary).</p>
- *
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.Parser#parse
- * @see org.xml.sax.EntityResolver#resolveEntity
- * @see java.io.InputStream
- * @see java.io.Reader
- */
-public class InputSource {
-    
-    /**
-     * Zero-argument default constructor.
-     *
-     * @see #setPublicId
-     * @see #setSystemId
-     * @see #setByteStream
-     * @see #setCharacterStream
-     * @see #setEncoding
-     */
-    public InputSource ()
-    {
-    }
-    
-    
-    /**
-     * Create a new input source with a system identifier.
-     *
-     * <p>Applications may use setPublicId to include a 
-     * public identifier as well, or setEncoding to specify
-     * the character encoding, if known.</p>
-     *
-     * <p>If the system identifier is a URL, it must be full resolved.</p>
-     *
-     * @param systemId The system identifier (URI).
-     * @see #setPublicId
-     * @see #setSystemId
-     * @see #setByteStream
-     * @see #setEncoding
-     * @see #setCharacterStream
-     */
-    public InputSource (String systemId)
-    {
-	setSystemId(systemId);
-    }
-    
-    
-    /**
-     * Create a new input source with a byte stream.
-     *
-     * <p>Application writers may use setSystemId to provide a base 
-     * for resolving relative URIs, setPublicId to include a 
-     * public identifier, and/or setEncoding to specify the object's
-     * character encoding.</p>
-     *
-     * @param byteStream The raw byte stream containing the document.
-     * @see #setPublicId
-     * @see #setSystemId
-     * @see #setEncoding
-     * @see #setByteStream
-     * @see #setCharacterStream
-     */
-    public InputSource (InputStream byteStream)
-    {
-	setByteStream(byteStream);
-    }
-    
-    
-    /**
-     * Create a new input source with a character stream.
-     *
-     * <p>Application writers may use setSystemId() to provide a base 
-     * for resolving relative URIs, and setPublicId to include a 
-     * public identifier.</p>
-     *
-     * <p>The character stream shall not include a byte order mark.</p>
-     *
-     * @see #setPublicId
-     * @see #setSystemId
-     * @see #setByteStream
-     * @see #setCharacterStream
-     */
-    public InputSource (Reader characterStream)
-    {
-	setCharacterStream(characterStream);
-    }
-    
-    
-    /**
-     * Set the public identifier for this input source.
-     *
-     * <p>The public identifier is always optional: if the application
-     * writer includes one, it will be provided as part of the
-     * location information.</p>
-     *
-     * @param publicId The public identifier as a string.
-     * @see #getPublicId
-     * @see org.xml.sax.Locator#getPublicId
-     * @see org.xml.sax.SAXParseException#getPublicId
-     */
-    public void setPublicId (String publicId)
-    {
-	this.publicId = publicId;
-    }
-    
-    
-    /**
-     * Get the public identifier for this input source.
-     *
-     * @return The public identifier, or null if none was supplied.
-     * @see #setPublicId
-     */
-    public String getPublicId ()
-    {
-	return publicId;
-    }
-    
-    
-    /**
-     * Set the system identifier for this input source.
-     *
-     * <p>The system identifier is optional if there is a byte stream
-     * or a character stream, but it is still useful to provide one,
-     * since the application can use it to resolve relative URIs
-     * and can include it in error messages and warnings (the parser
-     * will attempt to open a connection to the URI only if
-     * there is no byte stream or character stream specified).</p>
-     *
-     * <p>If the application knows the character encoding of the
-     * object pointed to by the system identifier, it can register
-     * the encoding using the setEncoding method.</p>
-     *
-     * <p>If the system ID is a URL, it must be fully resolved.</p>
-     *
-     * @param systemId The system identifier as a string.
-     * @see #setEncoding
-     * @see #getSystemId
-     * @see org.xml.sax.Locator#getSystemId
-     * @see org.xml.sax.SAXParseException#getSystemId
-     */
-    public void setSystemId (String systemId)
-    {
-	this.systemId = systemId;
-    }
-    
-    
-    /**
-     * Get the system identifier for this input source.
-     *
-     * <p>The getEncoding method will return the character encoding
-     * of the object pointed to, or null if unknown.</p>
-     *
-     * <p>If the system ID is a URL, it will be fully resolved.</p>
-     *
-     * @return The system identifier.
-     * @see #setSystemId
-     * @see #getEncoding
-     */
-    public String getSystemId ()
-    {
-	return systemId;
-    }
-    
-    
-    /**
-     * Set the byte stream for this input source.
-     *
-     * <p>The SAX parser will ignore this if there is also a character
-     * stream specified, but it will use a byte stream in preference
-     * to opening a URI connection itself.</p>
-     *
-     * <p>If the application knows the character encoding of the
-     * byte stream, it should set it with the setEncoding method.</p>
-     *
-     * @param byteStream A byte stream containing an XML document or
-     *        other entity.
-     * @see #setEncoding
-     * @see #getByteStream
-     * @see #getEncoding
-     * @see java.io.InputStream
-     */
-    public void setByteStream (InputStream byteStream)
-    {
-	this.byteStream = byteStream;
-    }
-    
-    
-    /**
-     * Get the byte stream for this input source.
-     *
-     * <p>The getEncoding method will return the character
-     * encoding for this byte stream, or null if unknown.</p>
-     *
-     * @return The byte stream, or null if none was supplied.
-     * @see #getEncoding
-     * @see #setByteStream
-     */
-    public InputStream getByteStream ()
-    {
-	return byteStream;
-    }
-    
-    
-    /** 
-     * Set the character encoding, if known.
-     *
-     * <p>The encoding must be a string acceptable for an
-     * XML encoding declaration (see section 4.3.3 of the XML 1.0
-     * recommendation).</p>
-     *
-     * <p>This method has no effect when the application provides a
-     * character stream.</p>
-     *
-     * @param encoding A string describing the character encoding.
-     * @see #setSystemId
-     * @see #setByteStream
-     * @see #getEncoding
-     */
-    public void setEncoding (String encoding)
-    {
-	this.encoding = encoding;
-    }
-    
-    
-    /**
-     * Get the character encoding for a byte stream or URI.
-     *
-     * @return The encoding, or null if none was supplied.
-     * @see #setByteStream
-     * @see #getSystemId
-     * @see #getByteStream
-     */
-    public String getEncoding ()
-    {
-	return encoding;
-    }
-    
-    
-    /**
-     * Set the character stream for this input source.
-     *
-     * <p>If there is a character stream specified, the SAX parser
-     * will ignore any byte stream and will not attempt to open
-     * a URI connection to the system identifier.</p>
-     *
-     * @param characterStream The character stream containing the
-     *        XML document or other entity.
-     * @see #getCharacterStream
-     * @see java.io.Reader
-     */
-    public void setCharacterStream (Reader characterStream)
-    {
-	this.characterStream = characterStream;
-    }
-    
-    
-    /**
-     * Get the character stream for this input source.
-     *
-     * @return The character stream, or null if none was supplied.
-     * @see #setCharacterStream
-     */
-    public Reader getCharacterStream ()
-    {
-	return characterStream;
-    }
-    
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Internal state.
-    ////////////////////////////////////////////////////////////////////
-    
-    private String publicId;
-    private String systemId;
-    private InputStream byteStream;
-    private String encoding;
-    private Reader characterStream;
-    
-}
-
-// end of InputSource.java
diff --git a/src/org/xml/sax/Locator.java b/src/org/xml/sax/Locator.java
deleted file mode 100644
index c69449a..0000000
--- a/src/org/xml/sax/Locator.java
+++ /dev/null
@@ -1,126 +0,0 @@
-// SAX locator interface for document events.
-// No warranty; no copyright -- use this as you will.
-// $Id: Locator.java,v 1.4 2000/05/05 17:46:57 david Exp $
-
-package org.xml.sax;
-
-
-/**
- * Interface for associating a SAX event with a document location.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>If a SAX parser provides location information to the SAX
- * application, it does so by implementing this interface and then
- * passing an instance to the application using the content
- * handler's {@link org.xml.sax.ContentHandler#setDocumentLocator
- * setDocumentLocator} method.  The application can use the
- * object to obtain the location of any other content handler event
- * in the XML source document.</p>
- *
- * <p>Note that the results returned by the object will be valid only
- * during the scope of each content handler method: the application
- * will receive unpredictable results if it attempts to use the
- * locator at any other time.</p>
- *
- * <p>SAX parsers are not required to supply a locator, but they are
- * very strongly encouraged to do so.  If the parser supplies a
- * locator, it must do so before reporting any other document events.
- * If no locator has been set by the time the application receives
- * the {@link org.xml.sax.ContentHandler#startDocument startDocument}
- * event, the application should assume that a locator is not 
- * available.</p>
- *
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.ContentHandler#setDocumentLocator 
- */
-public interface Locator {
-    
-    
-    /**
-     * Return the public identifier for the current document event.
-     *
-     * <p>The return value is the public identifier of the document
-     * entity or of the external parsed entity in which the markup
-     * triggering the event appears.</p>
-     *
-     * @return A string containing the public identifier, or
-     *         null if none is available.
-     * @see #getSystemId
-     */
-    public abstract String getPublicId ();
-    
-    
-    /**
-     * Return the system identifier for the current document event.
-     *
-     * <p>The return value is the system identifier of the document
-     * entity or of the external parsed entity in which the markup
-     * triggering the event appears.</p>
-     *
-     * <p>If the system identifier is a URL, the parser must resolve it
-     * fully before passing it to the application.</p>
-     *
-     * @return A string containing the system identifier, or null
-     *         if none is available.
-     * @see #getPublicId
-     */
-    public abstract String getSystemId ();
-    
-    
-    /**
-     * Return the line number where the current document event ends.
-     *
-     * <p><strong>Warning:</strong> The return value from the method
-     * is intended only as an approximation for the sake of error
-     * reporting; it is not intended to provide sufficient information
-     * to edit the character content of the original XML document.</p>
-     *
-     * <p>The return value is an approximation of the line number
-     * in the document entity or external parsed entity where the
-     * markup triggering the event appears.</p>
-     *
-     * <p>If possible, the SAX driver should provide the line position 
-     * of the first character after the text associated with the document 
-     * event.  The first line in the document is line 1.</p>
-     *
-     * @return The line number, or -1 if none is available.
-     * @see #getColumnNumber
-     */
-    public abstract int getLineNumber ();
-    
-    
-    /**
-     * Return the column number where the current document event ends.
-     *
-     * <p><strong>Warning:</strong> The return value from the method
-     * is intended only as an approximation for the sake of error
-     * reporting; it is not intended to provide sufficient information
-     * to edit the character content of the original XML document.</p>
-     *
-     * <p>The return value is an approximation of the column number
-     * in the document entity or external parsed entity where the
-     * markup triggering the event appears.</p>
-     *
-     * <p>If possible, the SAX driver should provide the line position 
-     * of the first character after the text associated with the document 
-     * event.</p>
-     *
-     * <p>If possible, the SAX driver should provide the line position 
-     * of the first character after the text associated with the document 
-     * event.  The first column in each line is column 1.</p>
-     *
-     * @return The column number, or -1 if none is available.
-     * @see #getLineNumber
-     */
-    public abstract int getColumnNumber ();
-    
-}
-
-// end of Locator.java
diff --git a/src/org/xml/sax/Makefile b/src/org/xml/sax/Makefile
deleted file mode 100644
index 30777d9..0000000
--- a/src/org/xml/sax/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-# Makefile for directory ./org/xml/sax
-
-TARGETS=\
-	Attributes.class\
-	AttributeList.class\
-	ContentHandler.class\
-	DocumentHandler.class\
-	DTDHandler.class\
-	EntityResolver.class\
-	ErrorHandler.class\
-	HandlerBase.class\
-	InputSource.class\
-	Locator.class\
-	Parser.class\
-	SAXException.class\
-	SAXNotRecognizedException.class\
-	SAXNotSupportedException.class\
-	SAXParseException.class\
-	XMLFilter.class\
-	XMLReader.class
-
-DIRS = helpers ext
-
-TOP = ../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/xml/sax/Parser.java b/src/org/xml/sax/Parser.java
deleted file mode 100644
index b9194af..0000000
--- a/src/org/xml/sax/Parser.java
+++ /dev/null
@@ -1,207 +0,0 @@
-// SAX parser interface.
-// No warranty; no copyright -- use this as you will.
-// $Id: Parser.java,v 1.5 2000/05/05 17:47:07 david Exp $
-
-package org.xml.sax;
-
-import java.io.IOException;
-import java.util.Locale;
-
-
-/**
- * Basic interface for SAX (Simple API for XML) parsers.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This was the main event supplier interface for SAX1; it has
- * been replaced in SAX2 by {@link org.xml.sax.XMLReader XMLReader},
- * which includes Namespace support and sophisticated configurability
- * and extensibility.</p>
- *
- * <p>All SAX1 parsers must implement this basic interface: it allows
- * applications to register handlers for different types of events
- * and to initiate a parse from a URI, or a character stream.</p>
- *
- * <p>All SAX1 parsers must also implement a zero-argument constructor
- * (though other constructors are also allowed).</p>
- *
- * <p>SAX1 parsers are reusable but not re-entrant: the application
- * may reuse a parser object (possibly with a different input source)
- * once the first parse has completed successfully, but it may not
- * invoke the parse() methods recursively within a parse.</p>
- *
- * @deprecated This interface has been replaced by the SAX2
- *             {@link org.xml.sax.XMLReader XMLReader}
- *             interface, which includes Namespace support.
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.EntityResolver
- * @see org.xml.sax.DTDHandler
- * @see org.xml.sax.DocumentHandler
- * @see org.xml.sax.ErrorHandler
- * @see org.xml.sax.HandlerBase
- * @see org.xml.sax.InputSource
- */
-public interface Parser 
-{
-    
-    /**
-     * Allow an application to request a locale for errors and warnings.
-     *
-     * <p>SAX parsers are not required to provide localisation for errors
-     * and warnings; if they cannot support the requested locale,
-     * however, they must throw a SAX exception.  Applications may
-     * not request a locale change in the middle of a parse.</p>
-     *
-     * @param locale A Java Locale object.
-     * @exception org.xml.sax.SAXException Throws an exception
-     *            (using the previous or default locale) if the 
-     *            requested locale is not supported.
-     * @see org.xml.sax.SAXException
-     * @see org.xml.sax.SAXParseException
-     */
-    public abstract void setLocale (Locale locale)
-	throws SAXException;
-    
-    
-    /**
-     * Allow an application to register a custom entity resolver.
-     *
-     * <p>If the application does not register an entity resolver, the
-     * SAX parser will resolve system identifiers and open connections
-     * to entities itself (this is the default behaviour implemented in
-     * HandlerBase).</p>
-     *
-     * <p>Applications may register a new or different entity resolver
-     * in the middle of a parse, and the SAX parser must begin using
-     * the new resolver immediately.</p>
-     *
-     * @param resolver The object for resolving entities.
-     * @see EntityResolver
-     * @see HandlerBase
-     */
-    public abstract void setEntityResolver (EntityResolver resolver);
-    
-    
-    /**
-     * Allow an application to register a DTD event handler.
-     *
-     * <p>If the application does not register a DTD handler, all DTD
-     * events reported by the SAX parser will be silently
-     * ignored (this is the default behaviour implemented by
-     * HandlerBase).</p>
-     *
-     * <p>Applications may register a new or different
-     * handler in the middle of a parse, and the SAX parser must
-     * begin using the new handler immediately.</p>
-     *
-     * @param handler The DTD handler.
-     * @see DTDHandler
-     * @see HandlerBase
-     */
-    public abstract void setDTDHandler (DTDHandler handler);
-    
-    
-    /**
-     * Allow an application to register a document event handler.
-     *
-     * <p>If the application does not register a document handler, all
-     * document events reported by the SAX parser will be silently
-     * ignored (this is the default behaviour implemented by
-     * HandlerBase).</p>
-     *
-     * <p>Applications may register a new or different handler in the
-     * middle of a parse, and the SAX parser must begin using the new
-     * handler immediately.</p>
-     *
-     * @param handler The document handler.
-     * @see DocumentHandler
-     * @see HandlerBase
-     */
-    public abstract void setDocumentHandler (DocumentHandler handler);
-    
-    
-    /**
-     * Allow an application to register an error event handler.
-     *
-     * <p>If the application does not register an error event handler,
-     * all error events reported by the SAX parser will be silently
-     * ignored, except for fatalError, which will throw a SAXException
-     * (this is the default behaviour implemented by HandlerBase).</p>
-     *
-     * <p>Applications may register a new or different handler in the
-     * middle of a parse, and the SAX parser must begin using the new
-     * handler immediately.</p>
-     *
-     * @param handler The error handler.
-     * @see ErrorHandler
-     * @see SAXException
-     * @see HandlerBase
-     */
-    public abstract void setErrorHandler (ErrorHandler handler);
-    
-    
-    /**
-     * Parse an XML document.
-     *
-     * <p>The application can use this method to instruct the SAX parser
-     * to begin parsing an XML document from any valid input
-     * source (a character stream, a byte stream, or a URI).</p>
-     *
-     * <p>Applications may not invoke this method while a parse is in
-     * progress (they should create a new Parser instead for each
-     * additional XML document).  Once a parse is complete, an
-     * application may reuse the same Parser object, possibly with a
-     * different input source.</p>
-     *
-     * @param source The input source for the top-level of the
-     *        XML document.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @exception java.io.IOException An IO exception from the parser,
-     *            possibly from a byte stream or character stream
-     *            supplied by the application.
-     * @see org.xml.sax.InputSource
-     * @see #parse(java.lang.String)
-     * @see #setEntityResolver
-     * @see #setDTDHandler
-     * @see #setDocumentHandler
-     * @see #setErrorHandler
-     */
-    public abstract void parse (InputSource source)
-	throws SAXException, IOException;
-    
-    
-    /**
-     * Parse an XML document from a system identifier (URI).
-     *
-     * <p>This method is a shortcut for the common case of reading a
-     * document from a system identifier.  It is the exact
-     * equivalent of the following:</p>
-     *
-     * <pre>
-     * parse(new InputSource(systemId));
-     * </pre>
-     *
-     * <p>If the system identifier is a URL, it must be fully resolved
-     * by the application before it is passed to the parser.</p>
-     *
-     * @param systemId The system identifier (URI).
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @exception java.io.IOException An IO exception from the parser,
-     *            possibly from a byte stream or character stream
-     *            supplied by the application.
-     * @see #parse(org.xml.sax.InputSource)
-     */
-    public abstract void parse (String systemId)
-	throws SAXException, IOException;
-    
-}
-
-// end of Parser.java
diff --git a/src/org/xml/sax/SAXException.java b/src/org/xml/sax/SAXException.java
deleted file mode 100644
index c952c40..0000000
--- a/src/org/xml/sax/SAXException.java
+++ /dev/null
@@ -1,144 +0,0 @@
-// SAX exception class.
-// No warranty; no copyright -- use this as you will.
-// $Id: SAXException.java,v 1.4 2000/05/05 17:47:20 david Exp $
-
-package org.xml.sax;
-
-/**
- * Encapsulate a general SAX error or warning.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This class can contain basic error or warning information from
- * either the XML parser or the application: a parser writer or
- * application writer can subclass it to provide additional
- * functionality.  SAX handlers may throw this exception or
- * any exception subclassed from it.</p>
- *
- * <p>If the application needs to pass through other types of
- * exceptions, it must wrap those exceptions in a SAXException
- * or an exception derived from a SAXException.</p>
- *
- * <p>If the parser or application needs to include information about a
- * specific location in an XML document, it should use the
- * {@link org.xml.sax.SAXParseException SAXParseException} subclass.</p>
- *
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.SAXParseException
- */
-public class SAXException extends Exception {
-    
-    
-    /**
-     * Create a new SAXException.
-     *
-     * @param message The error or warning message.
-     * @see org.xml.sax.Parser#setLocale
-     */
-    public SAXException (String message) {
-	super(message);
-	this.exception = null;
-    }
-    
-    
-    /**
-     * Create a new SAXException wrapping an existing exception.
-     *
-     * <p>The existing exception will be embedded in the new
-     * one, and its message will become the default message for
-     * the SAXException.</p>
-     *
-     * @param e The exception to be wrapped in a SAXException.
-     */
-    public SAXException (Exception e)
-    {
-	super();
-	this.exception = e;
-    }
-    
-    
-    /**
-     * Create a new SAXException from an existing exception.
-     *
-     * <p>The existing exception will be embedded in the new
-     * one, but the new exception will have its own message.</p>
-     *
-     * @param message The detail message.
-     * @param e The exception to be wrapped in a SAXException.
-     * @see org.xml.sax.Parser#setLocale
-     */
-    public SAXException (String message, Exception e)
-    {
-	super(message);
-	this.exception = e;
-    }
-    
-    
-    /**
-     * Return a detail message for this exception.
-     *
-     * <p>If there is an embedded exception, and if the SAXException
-     * has no detail message of its own, this method will return
-     * the detail message from the embedded exception.</p>
-     *
-     * @return The error or warning message.
-     * @see org.xml.sax.Parser#setLocale
-     */
-    public String getMessage ()
-    {
-	String message = super.getMessage();
-	
-	if (message == null && exception != null) {
-	    return exception.getMessage();
-	} else {
-	    return message;
-	}
-    }
-    
-    
-    /**
-     * Return the embedded exception, if any.
-     *
-     * @return The embedded exception, or null if there is none.
-     */
-    public Exception getException ()
-    {
-	return exception;
-    }
-
-
-    /**
-     * Override toString to pick up any embedded exception.
-     *
-     * @return A string representation of this exception.
-     */
-    public String toString ()
-    {
-	if (exception != null) {
-	    return exception.toString();
-	} else {
-	    return super.toString();
-	}
-    }
-    
-    
-    
-    //////////////////////////////////////////////////////////////////////
-    // Internal state.
-    //////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * @serial The embedded exception if tunnelling, or null.
-     */    
-    private Exception exception;
-    
-}
-
-// end of SAXException.java
diff --git a/src/org/xml/sax/SAXNotRecognizedException.java b/src/org/xml/sax/SAXNotRecognizedException.java
deleted file mode 100644
index ee0895f..0000000
--- a/src/org/xml/sax/SAXNotRecognizedException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// SAXNotRecognizedException.java - unrecognized feature or value.
-// Written by David Megginson, sax@megginson.com
-// NO WARRANTY!  This class is in the Public Domain.
-
-// $Id: SAXNotRecognizedException.java,v 1.4 2000/05/05 17:47:28 david Exp $
-
-
-package org.xml.sax;
-
-
-/**
- * Exception class for an unrecognized identifier.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>An XMLReader will throw this exception when it finds an
- * unrecognized feature or property identifier; SAX applications and
- * extensions may use this class for other, similar purposes.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.SAXNotSupportedException
- */
-public class SAXNotRecognizedException extends SAXException
-{
-
-    /**
-     * Construct a new exception with the given message.
-     *
-     * @param message The text message of the exception.
-     */
-    public SAXNotRecognizedException (String message)
-    {
-	super(message);
-    }
-
-}
-
-// end of SAXNotRecognizedException.java
diff --git a/src/org/xml/sax/SAXNotSupportedException.java b/src/org/xml/sax/SAXNotSupportedException.java
deleted file mode 100644
index 013b063..0000000
--- a/src/org/xml/sax/SAXNotSupportedException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// SAXNotSupportedException.java - unsupported feature or value.
-// Written by David Megginson, sax@megginson.com
-// NO WARRANTY!  This class is in the Public Domain.
-
-// $Id: SAXNotSupportedException.java,v 1.5 2000/05/05 17:47:39 david Exp $
-
-
-package org.xml.sax;
-
-/**
- * Exception class for an unsupported operation.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>An XMLReader will throw this exception when it recognizes a
- * feature or property identifier, but cannot perform the requested
- * operation (setting a state or value).  Other SAX2 applications and
- * extensions may use this class for similar purposes.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.SAXNotRecognizedException 
- */
-public class SAXNotSupportedException extends SAXException
-{
-
-    /**
-     * Construct a new exception with the given message.
-     *
-     * @param message The text message of the exception.
-     */
-    public SAXNotSupportedException (String message)
-    {
-	super(message);
-    }
-
-}
-
-// end of SAXNotSupportedException.java
diff --git a/src/org/xml/sax/SAXParseException.java b/src/org/xml/sax/SAXParseException.java
deleted file mode 100644
index 8890442..0000000
--- a/src/org/xml/sax/SAXParseException.java
+++ /dev/null
@@ -1,264 +0,0 @@
-// SAX exception class.
-// No warranty; no copyright -- use this as you will.
-// $Id: SAXParseException.java,v 1.4 2000/05/05 17:48:16 david Exp $
-
-package org.xml.sax;
-
-/**
- * Encapsulate an XML parse error or warning.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This exception will include information for locating the error
- * in the original XML document.  Note that although the application
- * will receive a SAXParseException as the argument to the handlers
- * in the {@link org.xml.sax.ErrorHandler ErrorHandler} interface, 
- * the application is not actually required to throw the exception; 
- * instead, it can simply read the information in it and take a 
- * different action.</p>
- *
- * <p>Since this exception is a subclass of {@link org.xml.sax.SAXException 
- * SAXException}, it inherits the ability to wrap another exception.</p>
- *
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.SAXException
- * @see org.xml.sax.Locator
- * @see org.xml.sax.ErrorHandler
- */
-public class SAXParseException extends SAXException {
-    
-    
-    //////////////////////////////////////////////////////////////////////
-    // Constructors.
-    //////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Create a new SAXParseException from a message and a Locator.
-     *
-     * <p>This constructor is especially useful when an application is
-     * creating its own exception from within a {@link org.xml.sax.ContentHandler
-     * ContentHandler} callback.</p>
-     *
-     * @param message The error or warning message.
-     * @param locator The locator object for the error or warning (may be
-     *        null).
-     * @see org.xml.sax.Locator
-     * @see org.xml.sax.Parser#setLocale 
-     */
-    public SAXParseException (String message, Locator locator) {
-	super(message);
-	if (locator != null) {
-	    init(locator.getPublicId(), locator.getSystemId(),
-		 locator.getLineNumber(), locator.getColumnNumber());
-	} else {
-	    init(null, null, -1, -1);
-	}
-    }
-    
-    
-    /**
-     * Wrap an existing exception in a SAXParseException.
-     *
-     * <p>This constructor is especially useful when an application is
-     * creating its own exception from within a {@link org.xml.sax.ContentHandler
-     * ContentHandler} callback, and needs to wrap an existing exception that is not a
-     * subclass of {@link org.xml.sax.SAXException SAXException}.</p>
-     *
-     * @param message The error or warning message, or null to
-     *                use the message from the embedded exception.
-     * @param locator The locator object for the error or warning (may be
-     *        null).
-     * @param e Any exception.
-     * @see org.xml.sax.Locator
-     * @see org.xml.sax.Parser#setLocale
-     */
-    public SAXParseException (String message, Locator locator,
-			      Exception e) {
-	super(message, e);
-	if (locator != null) {
-	    init(locator.getPublicId(), locator.getSystemId(),
-		 locator.getLineNumber(), locator.getColumnNumber());
-	} else {
-	    init(null, null, -1, -1);
-	}
-    }
-    
-    
-    /**
-     * Create a new SAXParseException.
-     *
-     * <p>This constructor is most useful for parser writers.</p>
-     *
-     * <p>If the system identifier is a URL, the parser must resolve it
-     * fully before creating the exception.</p>
-     *
-     * @param message The error or warning message.
-     * @param publicId The public identifer of the entity that generated
-     *                 the error or warning.
-     * @param systemId The system identifer of the entity that generated
-     *                 the error or warning.
-     * @param lineNumber The line number of the end of the text that
-     *                   caused the error or warning.
-     * @param columnNumber The column number of the end of the text that
-     *                     cause the error or warning.
-     * @see org.xml.sax.Parser#setLocale
-     */
-    public SAXParseException (String message, String publicId, String systemId,
-			      int lineNumber, int columnNumber)
-    {
-	super(message);
-	init(publicId, systemId, lineNumber, columnNumber);
-    }
-    
-    
-    /**
-     * Create a new SAXParseException with an embedded exception.
-     *
-     * <p>This constructor is most useful for parser writers who
-     * need to wrap an exception that is not a subclass of
-     * {@link org.xml.sax.SAXException SAXException}.</p>
-     *
-     * <p>If the system identifier is a URL, the parser must resolve it
-     * fully before creating the exception.</p>
-     *
-     * @param message The error or warning message, or null to use
-     *                the message from the embedded exception.
-     * @param publicId The public identifer of the entity that generated
-     *                 the error or warning.
-     * @param systemId The system identifer of the entity that generated
-     *                 the error or warning.
-     * @param lineNumber The line number of the end of the text that
-     *                   caused the error or warning.
-     * @param columnNumber The column number of the end of the text that
-     *                     cause the error or warning.
-     * @param e Another exception to embed in this one.
-     * @see org.xml.sax.Parser#setLocale
-     */
-    public SAXParseException (String message, String publicId, String systemId,
-			      int lineNumber, int columnNumber, Exception e)
-    {
-	super(message, e);
-	init(publicId, systemId, lineNumber, columnNumber);
-    }
-
-
-    /**
-     * Internal initialization method.
-     *
-     * @param publicId The public identifier of the entity which generated the exception,
-     *        or null.
-     * @param systemId The system identifier of the entity which generated the exception,
-     *        or null.
-     * @param lineNumber The line number of the error, or -1.
-     * @param columnNumber The column number of the error, or -1.
-     */
-    private void init (String publicId, String systemId,
-		       int lineNumber, int columnNumber)
-    {
-	this.publicId = publicId;
-	this.systemId = systemId;
-	this.lineNumber = lineNumber;
-	this.columnNumber = columnNumber;
-    }
-    
-    
-    /**
-     * Get the public identifier of the entity where the exception occurred.
-     *
-     * @return A string containing the public identifier, or null
-     *         if none is available.
-     * @see org.xml.sax.Locator#getPublicId
-     */
-    public String getPublicId ()
-    {
-	return this.publicId;
-    }
-    
-    
-    /**
-     * Get the system identifier of the entity where the exception occurred.
-     *
-     * <p>If the system identifier is a URL, it will be resolved
-     * fully.</p>
-     *
-     * @return A string containing the system identifier, or null
-     *         if none is available.
-     * @see org.xml.sax.Locator#getSystemId
-     */
-    public String getSystemId ()
-    {
-	return this.systemId;
-    }
-    
-    
-    /**
-     * The line number of the end of the text where the exception occurred.
-     *
-     * @return An integer representing the line number, or -1
-     *         if none is available.
-     * @see org.xml.sax.Locator#getLineNumber
-     */
-    public int getLineNumber ()
-    {
-	return this.lineNumber;
-    }
-    
-    
-    /**
-     * The column number of the end of the text where the exception occurred.
-     *
-     * <p>The first column in a line is position 1.</p>
-     *
-     * @return An integer representing the column number, or -1
-     *         if none is available.
-     * @see org.xml.sax.Locator#getColumnNumber
-     */
-    public int getColumnNumber ()
-    {
-	return this.columnNumber;
-    }
-    
-    
-    
-    //////////////////////////////////////////////////////////////////////
-    // Internal state.
-    //////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * @serial The public identifier, or null.
-     * @see #getPublicId
-     */    
-    private String publicId;
-
-
-    /**
-     * @serial The system identifier, or null.
-     * @see #getSystemId
-     */
-    private String systemId;
-
-
-    /**
-     * @serial The line number, or -1.
-     * @see #getLineNumber
-     */
-    private int lineNumber;
-
-
-    /**
-     * @serial The column number, or -1.
-     * @see #getColumnNumber
-     */
-    private int columnNumber;
-    
-}
-
-// end of SAXParseException.java
diff --git a/src/org/xml/sax/XMLFilter.java b/src/org/xml/sax/XMLFilter.java
deleted file mode 100644
index 86ff045..0000000
--- a/src/org/xml/sax/XMLFilter.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// XMLFilter.java - filter SAX2 events.
-// Written by David Megginson, sax@megginson.com
-// NO WARRANTY!  This class is in the Public Domain.
-
-// $Id: XMLFilter.java,v 1.4 2000/05/05 17:48:25 david Exp $
-
-
-package org.xml.sax;
-
-
-/**
- * Interface for an XML filter.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>An XML filter is like an XML reader, except that it obtains its
- * events from another XML reader rather than a primary source like
- * an XML document or database.  Filters can modify a stream of
- * events as they pass on to the final application.</p>
- *
- * <p>The XMLFilterImpl helper class provides a convenient base
- * for creating SAX2 filters, by passing on all {@link org.xml.sax.EntityResolver
- * EntityResolver}, {@link org.xml.sax.DTDHandler DTDHandler},
- * {@link org.xml.sax.ContentHandler ContentHandler} and {@link org.xml.sax.ErrorHandler
- * ErrorHandler} events automatically.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.helpers.XMLFilterImpl
- */
-public interface XMLFilter extends XMLReader
-{
-
-    /**
-     * Set the parent reader.
-     *
-     * <p>This method allows the application to link the filter to
-     * a parent reader (which may be another filter).  The argument
-     * may not be null.</p>
-     *
-     * @param parent The parent reader.
-     */
-    public abstract void setParent (XMLReader parent);
-
-
-    /**
-     * Get the parent reader.
-     *
-     * <p>This method allows the application to query the parent
-     * reader (which may be another filter).  It is generally a
-     * bad idea to perform any operations on the parent reader
-     * directly: they should all pass through this filter.</p>
-     *
-     * @return The parent filter, or null if none has been set.
-     */
-    public abstract XMLReader getParent ();
-
-}
-
-// end of XMLFilter.java
diff --git a/src/org/xml/sax/XMLReader.java b/src/org/xml/sax/XMLReader.java
deleted file mode 100644
index 80b82ba..0000000
--- a/src/org/xml/sax/XMLReader.java
+++ /dev/null
@@ -1,415 +0,0 @@
-// XMLReader.java - read an XML document.
-// Written by David Megginson, sax@megginson.com
-// NO WARRANTY!  This class is in the Public Domain.
-
-// $Id: XMLReader.java,v 1.6 2000/05/05 17:48:56 david Exp $
-
-package org.xml.sax;
-
-import java.io.IOException;
-
-
-/**
- * Interface for reading an XML document using callbacks.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p><strong>Note:</strong> despite its name, this interface does 
- * <em>not</em> extend the standard Java {@link java.io.Reader Reader} 
- * interface, because reading XML is a fundamentally different activity 
- * than reading character data.</p>
- *
- * <p>XMLReader is the interface that an XML parser's SAX2 driver must
- * implement.  This interface allows an application to set and
- * query features and properties in the parser, to register
- * event handlers for document processing, and to initiate
- * a document parse.</p>
- *
- * <p>All SAX interfaces are assumed to be synchronous: the
- * {@link #parse parse} methods must not return until parsing
- * is complete, and readers must wait for an event-handler callback
- * to return before reporting the next event.</p>
- *
- * <p>This interface replaces the (now deprecated) SAX 1.0 {@link
- * org.xml.sax.Parser Parser} interface.  The XMLReader interface
- * contains two important enhancements over the old Parser
- * interface:</p>
- *
- * <ol>
- * <li>it adds a standard way to query and set features and 
- *  properties; and</li>
- * <li>it adds Namespace support, which is required for many
- *  higher-level XML standards.</li>
- * </ol>
- *
- * <p>There are adapters available to convert a SAX1 Parser to
- * a SAX2 XMLReader and vice-versa.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.XMLFilter
- * @see org.xml.sax.helpers.ParserAdapter
- * @see org.xml.sax.helpers.XMLReaderAdapter 
- */
-public interface XMLReader
-{
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Configuration.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Look up the value of a feature.
-     *
-     * <p>The feature name is any fully-qualified URI.  It is
-     * possible for an XMLReader to recognize a feature name but
-     * to be unable to return its value; this is especially true
-     * in the case of an adapter for a SAX1 Parser, which has
-     * no way of knowing whether the underlying parser is
-     * performing validation or expanding external entities.</p>
-     *
-     * <p>All XMLReaders are required to recognize the
-     * http://xml.org/sax/features/namespaces and the
-     * http://xml.org/sax/features/namespace-prefixes feature names.</p>
-     *
-     * <p>Some feature values may be available only in specific
-     * contexts, such as before, during, or after a parse.</p>
-     *
-     * <p>Typical usage is something like this:</p>
-     *
-     * <pre>
-     * XMLReader r = new MySAXDriver();
-     *
-     *                         // try to activate validation
-     * try {
-     *   r.setFeature("http://xml.org/sax/features/validation", true);
-     * } catch (SAXException e) {
-     *   System.err.println("Cannot activate validation."); 
-     * }
-     *
-     *                         // register event handlers
-     * r.setContentHandler(new MyContentHandler());
-     * r.setErrorHandler(new MyErrorHandler());
-     *
-     *                         // parse the first document
-     * try {
-     *   r.parse("http://www.foo.com/mydoc.xml");
-     * } catch (IOException e) {
-     *   System.err.println("I/O exception reading XML document");
-     * } catch (SAXException e) {
-     *   System.err.println("XML exception reading document.");
-     * }
-     * </pre>
-     *
-     * <p>Implementors are free (and encouraged) to invent their own features,
-     * using names built on their own URIs.</p>
-     *
-     * @param name The feature name, which is a fully-qualified URI.
-     * @return The current state of the feature (true or false).
-     * @exception org.xml.sax.SAXNotRecognizedException When the
-     *            XMLReader does not recognize the feature name.
-     * @exception org.xml.sax.SAXNotSupportedException When the
-     *            XMLReader recognizes the feature name but 
-     *            cannot determine its value at this time.
-     * @see #setFeature
-     */
-    public boolean getFeature (String name)
-        throws SAXNotRecognizedException, SAXNotSupportedException;
-
-
-    /**
-     * Set the state of a feature.
-     *
-     * <p>The feature name is any fully-qualified URI.  It is
-     * possible for an XMLReader to recognize a feature name but
-     * to be unable to set its value; this is especially true
-     * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser Parser},
-     * which has no way of affecting whether the underlying parser is
-     * validating, for example.</p>
-     *
-     * <p>All XMLReaders are required to support setting
-     * http://xml.org/sax/features/namespaces to true and
-     * http://xml.org/sax/features/namespace-prefixes to false.</p>
-     *
-     * <p>Some feature values may be immutable or mutable only 
-     * in specific contexts, such as before, during, or after 
-     * a parse.</p>
-     *
-     * @param name The feature name, which is a fully-qualified URI.
-     * @param state The requested state of the feature (true or false).
-     * @exception org.xml.sax.SAXNotRecognizedException When the
-     *            XMLReader does not recognize the feature name.
-     * @exception org.xml.sax.SAXNotSupportedException When the
-     *            XMLReader recognizes the feature name but 
-     *            cannot set the requested value.
-     * @see #getFeature
-     */
-    public void setFeature (String name, boolean value)
-	throws SAXNotRecognizedException, SAXNotSupportedException;
-
-
-    /**
-     * Look up the value of a property.
-     *
-     * <p>The property name is any fully-qualified URI.  It is
-     * possible for an XMLReader to recognize a property name but
-     * to be unable to return its state; this is especially true
-     * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser
-     * Parser}.</p>
-     *
-     * <p>XMLReaders are not required to recognize any specific
-     * property names, though an initial core set is documented for
-     * SAX2.</p>
-     *
-     * <p>Some property values may be available only in specific
-     * contexts, such as before, during, or after a parse.</p>
-     *
-     * <p>Implementors are free (and encouraged) to invent their own properties,
-     * using names built on their own URIs.</p>
-     *
-     * @param name The property name, which is a fully-qualified URI.
-     * @return The current value of the property.
-     * @exception org.xml.sax.SAXNotRecognizedException When the
-     *            XMLReader does not recognize the property name.
-     * @exception org.xml.sax.SAXNotSupportedException When the
-     *            XMLReader recognizes the property name but 
-     *            cannot determine its value at this time.
-     * @see #setProperty
-     */
-    public Object getProperty (String name)
-	throws SAXNotRecognizedException, SAXNotSupportedException;
-
-
-    /**
-     * Set the value of a property.
-     *
-     * <p>The property name is any fully-qualified URI.  It is
-     * possible for an XMLReader to recognize a property name but
-     * to be unable to set its value; this is especially true
-     * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser
-     * Parser}.</p>
-     *
-     * <p>XMLReaders are not required to recognize setting
-     * any specific property names, though a core set is provided with 
-     * SAX2.</p>
-     *
-     * <p>Some property values may be immutable or mutable only 
-     * in specific contexts, such as before, during, or after 
-     * a parse.</p>
-     *
-     * <p>This method is also the standard mechanism for setting
-     * extended handlers.</p>
-     *
-     * @param name The property name, which is a fully-qualified URI.
-     * @param state The requested value for the property.
-     * @exception org.xml.sax.SAXNotRecognizedException When the
-     *            XMLReader does not recognize the property name.
-     * @exception org.xml.sax.SAXNotSupportedException When the
-     *            XMLReader recognizes the property name but 
-     *            cannot set the requested value.
-     */
-    public void setProperty (String name, Object value)
-	throws SAXNotRecognizedException, SAXNotSupportedException;
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Event handlers.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Allow an application to register an entity resolver.
-     *
-     * <p>If the application does not register an entity resolver,
-     * the XMLReader will perform its own default resolution.</p>
-     *
-     * <p>Applications may register a new or different resolver in the
-     * middle of a parse, and the SAX parser must begin using the new
-     * resolver immediately.</p>
-     *
-     * @param resolver The entity resolver.
-     * @exception java.lang.NullPointerException If the resolver 
-     *            argument is null.
-     * @see #getEntityResolver
-     */
-    public void setEntityResolver (EntityResolver resolver);
-
-
-    /**
-     * Return the current entity resolver.
-     *
-     * @return The current entity resolver, or null if none
-     *         has been registered.
-     * @see #setEntityResolver
-     */
-    public EntityResolver getEntityResolver ();
-
-
-    /**
-     * Allow an application to register a DTD event handler.
-     *
-     * <p>If the application does not register a DTD handler, all DTD
-     * events reported by the SAX parser will be silently ignored.</p>
-     *
-     * <p>Applications may register a new or different handler in the
-     * middle of a parse, and the SAX parser must begin using the new
-     * handler immediately.</p>
-     *
-     * @param handler The DTD handler.
-     * @exception java.lang.NullPointerException If the handler 
-     *            argument is null.
-     * @see #getDTDHandler
-     */
-    public void setDTDHandler (DTDHandler handler);
-
-
-    /**
-     * Return the current DTD handler.
-     *
-     * @return The current DTD handler, or null if none
-     *         has been registered.
-     * @see #setDTDHandler
-     */
-    public DTDHandler getDTDHandler ();
-
-
-    /**
-     * Allow an application to register a content event handler.
-     *
-     * <p>If the application does not register a content handler, all
-     * content events reported by the SAX parser will be silently
-     * ignored.</p>
-     *
-     * <p>Applications may register a new or different handler in the
-     * middle of a parse, and the SAX parser must begin using the new
-     * handler immediately.</p>
-     *
-     * @param handler The content handler.
-     * @exception java.lang.NullPointerException If the handler 
-     *            argument is null.
-     * @see #getContentHandler
-     */
-    public void setContentHandler (ContentHandler handler);
-
-
-    /**
-     * Return the current content handler.
-     *
-     * @return The current content handler, or null if none
-     *         has been registered.
-     * @see #setContentHandler
-     */
-    public ContentHandler getContentHandler ();
-
-
-    /**
-     * Allow an application to register an error event handler.
-     *
-     * <p>If the application does not register an error handler, all
-     * error events reported by the SAX parser will be silently
-     * ignored; however, normal processing may not continue.  It is
-     * highly recommended that all SAX applications implement an
-     * error handler to avoid unexpected bugs.</p>
-     *
-     * <p>Applications may register a new or different handler in the
-     * middle of a parse, and the SAX parser must begin using the new
-     * handler immediately.</p>
-     *
-     * @param handler The error handler.
-     * @exception java.lang.NullPointerException If the handler 
-     *            argument is null.
-     * @see #getErrorHandler
-     */
-    public void setErrorHandler (ErrorHandler handler);
-
-
-    /**
-     * Return the current error handler.
-     *
-     * @return The current error handler, or null if none
-     *         has been registered.
-     * @see #setErrorHandler
-     */
-    public ErrorHandler getErrorHandler ();
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Parsing.
-    ////////////////////////////////////////////////////////////////////
-
-    /**
-     * Parse an XML document.
-     *
-     * <p>The application can use this method to instruct the XML
-     * reader to begin parsing an XML document from any valid input
-     * source (a character stream, a byte stream, or a URI).</p>
-     *
-     * <p>Applications may not invoke this method while a parse is in
-     * progress (they should create a new XMLReader instead for each
-     * nested XML document).  Once a parse is complete, an
-     * application may reuse the same XMLReader object, possibly with a
-     * different input source.</p>
-     *
-     * <p>During the parse, the XMLReader will provide information
-     * about the XML document through the registered event
-     * handlers.</p>
-     *
-     * <p>This method is synchronous: it will not return until parsing
-     * has ended.  If a client application wants to terminate 
-     * parsing early, it should throw an exception.</p>
-     *
-     * @param source The input source for the top-level of the
-     *        XML document.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @exception java.io.IOException An IO exception from the parser,
-     *            possibly from a byte stream or character stream
-     *            supplied by the application.
-     * @see org.xml.sax.InputSource
-     * @see #parse(java.lang.String)
-     * @see #setEntityResolver
-     * @see #setDTDHandler
-     * @see #setContentHandler
-     * @see #setErrorHandler 
-     */
-    public void parse (InputSource input)
-	throws IOException, SAXException;
-
-
-    /**
-     * Parse an XML document from a system identifier (URI).
-     *
-     * <p>This method is a shortcut for the common case of reading a
-     * document from a system identifier.  It is the exact
-     * equivalent of the following:</p>
-     *
-     * <pre>
-     * parse(new InputSource(systemId));
-     * </pre>
-     *
-     * <p>If the system identifier is a URL, it must be fully resolved
-     * by the application before it is passed to the parser.</p>
-     *
-     * @param systemId The system identifier (URI).
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @exception java.io.IOException An IO exception from the parser,
-     *            possibly from a byte stream or character stream
-     *            supplied by the application.
-     * @see #parse(org.xml.sax.InputSource)
-     */
-    public void parse (String systemId)
-	throws IOException, SAXException;
-
-}
-
-// end of XMLReader.java
diff --git a/src/org/xml/sax/ext/DeclHandler.java b/src/org/xml/sax/ext/DeclHandler.java
deleted file mode 100644
index a507118..0000000
--- a/src/org/xml/sax/ext/DeclHandler.java
+++ /dev/null
@@ -1,131 +0,0 @@
-// DeclHandler.java - Optional handler for DTD declaration events.
-// Public Domain: no warranty.
-// $Id: DeclHandler.java,v 1.2 2000/01/28 16:38:07 david Exp $
-
-package org.xml.sax.ext;
-
-import org.xml.sax.SAXException;
-
-
-/**
- * SAX2 extension handler for DTD declaration events.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This is an optional extension handler for SAX2 to provide
- * information about DTD declarations in an XML document.  XML
- * readers are not required to support this handler.</p>
- *
- * <p>Note that data-related DTD declarations (unparsed entities and
- * notations) are already reported through the {@link
- * org.xml.sax.DTDHandler DTDHandler} interface.</p>
- *
- * <p>If you are using the declaration handler together with a lexical
- * handler, all of the events will occur between the
- * {@link org.xml.sax.ext.LexicalHandler#startDTD startDTD} and the
- * {@link org.xml.sax.ext.LexicalHandler#endDTD endDTD} events.</p>
- *
- * <p>To set the DeclHandler for an XML reader, use the
- * {@link org.xml.sax.XMLReader#setProperty setProperty} method
- * with the propertyId "http://xml.org/sax/handlers/DeclHandler".
- * If the reader does not support declaration events, it will throw a
- * {@link org.xml.sax.SAXNotRecognizedException SAXNotRecognizedException}
- * or a
- * {@link org.xml.sax.SAXNotSupportedException SAXNotSupportedException}
- * when you attempt to register the handler.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0beta
- * @see org.xml.sax.XMLReader
- */
-public interface DeclHandler
-{
-
-    /**
-     * Report an element type declaration.
-     *
-     * <p>The content model will consist of the string "EMPTY", the
-     * string "ANY", or a parenthesised group, optionally followed
-     * by an occurrence indicator.  The model will be normalized so
-     * that all whitespace is removed,and will include the enclosing
-     * parentheses.</p>
-     *
-     * @param name The element type name.
-     * @param model The content model as a normalized string.
-     * @exception SAXException The application may raise an exception.
-     */
-    public abstract void elementDecl (String name, String model)
-	throws SAXException;
-
-
-    /**
-     * Report an attribute type declaration.
-     *
-     * <p>Only the effective (first) declaration for an attribute will
-     * be reported.  The type will be one of the strings "CDATA",
-     * "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY",
-     * "ENTITIES", or "NOTATION", or a parenthesized token group with 
-     * the separator "|" and all whitespace removed.</p>
-     *
-     * @param eName The name of the associated element.
-     * @param aName The name of the attribute.
-     * @param type A string representing the attribute type.
-     * @param valueDefault A string representing the attribute default
-     *        ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if
-     *        none of these applies.
-     * @param value A string representing the attribute's default value,
-     *        or null if there is none.
-     * @exception SAXException The application may raise an exception.
-     */
-    public abstract void attributeDecl (String eName,
-					String aName,
-					String type,
-					String valueDefault,
-					String value)
-	throws SAXException;
-
-
-    /**
-     * Report an internal entity declaration.
-     *
-     * <p>Only the effective (first) declaration for each entity
-     * will be reported.</p>
-     *
-     * @param name The name of the entity.  If it is a parameter
-     *        entity, the name will begin with '%'.
-     * @param value The replacement text of the entity.
-     * @exception SAXException The application may raise an exception.
-     * @see #externalEntityDecl
-     * @see org.xml.sax.DTDHandler#unparsedEntityDecl
-     */
-    public abstract void internalEntityDecl (String name, String value)
-	throws SAXException;
-
-
-    /**
-     * Report a parsed external entity declaration.
-     *
-     * <p>Only the effective (first) declaration for each entity
-     * will be reported.</p>
-     *
-     * @param name The name of the entity.  If it is a parameter
-     *        entity, the name will begin with '%'.
-     * @param publicId The declared public identifier of the entity, or
-     *        null if none was declared.
-     * @param systemId The declared system identifier of the entity.
-     * @exception SAXException The application may raise an exception.
-     * @see #internalEntityDecl
-     * @see org.xml.sax.DTDHandler#unparsedEntityDecl
-     */
-    public abstract void externalEntityDecl (String name, String publicId,
-					     String systemId)
-	throws SAXException;
-
-}
-
-// end of DeclHandler.java
diff --git a/src/org/xml/sax/ext/LexicalHandler.java b/src/org/xml/sax/ext/LexicalHandler.java
deleted file mode 100644
index f28a82e..0000000
--- a/src/org/xml/sax/ext/LexicalHandler.java
+++ /dev/null
@@ -1,161 +0,0 @@
-// LexicalHandler.java - optional handler for lexical parse events.
-// Public Domain: no warranty.
-// $Id: LexicalHandler.java,v 1.4 2000/02/25 14:55:59 david Exp $
-
-package org.xml.sax.ext;
-
-import org.xml.sax.SAXException;
-
-/**
- * SAX2 extension handler for lexical events.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This is an optional extension handler for SAX2 to provide
- * lexical information about an XML document, such as comments
- * and CDATA section boundaries; XML readers are not required to 
- * support this handler.</p>
- *
- * <p>The events in the lexical handler apply to the entire document,
- * not just to the document element, and all lexical handler events
- * must appear between the content handler's startDocument and
- * endDocument events.</p>
- *
- * <p>To set the LexicalHandler for an XML reader, use the
- * {@link org.xml.sax.XMLReader#setProperty setProperty} method
- * with the propertyId "http://xml.org/sax/handlers/LexicalHandler".
- * If the reader does not support lexical events, it will throw a
- * {@link org.xml.sax.SAXNotRecognizedException SAXNotRecognizedException}
- * or a
- * {@link org.xml.sax.SAXNotSupportedException SAXNotSupportedException}
- * when you attempt to register the handler.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0beta
- * @see org.xml.sax.XMLReader#setProperty
- * @see org.xml.sax.SAXNotRecognizedException
- * @see org.xml.sax.SAXNotSupportedException
- */
-public interface LexicalHandler
-{
-
-    /**
-     * Report the start of DTD declarations, if any.
-     *
-     * <p>Any declarations are assumed to be in the internal subset
-     * unless otherwise indicated by a {@link #startEntity startEntity}
-     * event.</p>
-     *
-     * <p>Note that the start/endDTD events will appear within
-     * the start/endDocument events from ContentHandler and
-     * before the first startElement event.</p>
-     *
-     * @param name The document type name.
-     * @param publicId The declared public identifier for the
-     *        external DTD subset, or null if none was declared.
-     * @param systemId The declared system identifier for the
-     *        external DTD subset, or null if none was declared.
-     * @exception SAXException The application may raise an
-     *            exception.
-     * @see #endDTD
-     * @see #startEntity
-     */
-    public abstract void startDTD (String name, String publicId,
-				   String systemId)
-	throws SAXException;
-
-
-    /**
-     * Report the end of DTD declarations.
-     *
-     * @exception SAXException The application may raise an exception.
-     * @see #startDTD
-     */
-    public abstract void endDTD ()
-	throws SAXException;
-
-
-    /**
-     * Report the beginning of an entity in content.
-     *
-     * <p><strong>NOTE:</entity> entity references in attribute
-     * values -- and the start and end of the document entity --
-     * are never reported.</p>
-     *
-     * <p>The start and end of the external DTD subset are reported
-     * using the pseudo-name "[dtd]".  All other events must be
-     * properly nested within start/end entity events.</p>
-     *
-     * <p>Note that skipped entities will be reported through the
-     * {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity}
-     * event, which is part of the ContentHandler interface.</p>
-     *
-     * @param name The name of the entity.  If it is a parameter
-     *        entity, the name will begin with '%'.
-     * @exception SAXException The application may raise an exception.
-     * @see #endEntity
-     * @see org.xml.sax.ext.DeclHandler#internalEntityDecl
-     * @see org.xml.sax.ext.DeclHandler#externalEntityDecl
-     */
-    public abstract void startEntity (String name)
-	throws SAXException;
-
-
-    /**
-     * Report the end of an entity.
-     *
-     * @param name The name of the entity that is ending.
-     * @exception SAXException The application may raise an exception.
-     * @see #startEntity
-     */
-    public abstract void endEntity (String name)
-	throws SAXException;
-
-
-    /**
-     * Report the start of a CDATA section.
-     *
-     * <p>The contents of the CDATA section will be reported through
-     * the regular {@link org.xml.sax.ContentHandler#characters
-     * characters} event.</p>
-     *
-     * @exception SAXException The application may raise an exception.
-     * @see #endCDATA
-     */
-    public abstract void startCDATA ()
-	throws SAXException;
-
-
-    /**
-     * Report the end of a CDATA section.
-     *
-     * @exception SAXException The application may raise an exception.
-     * @see #startCDATA
-     */
-    public abstract void endCDATA ()
-	throws SAXException;
-
-
-    /**
-     * Report an XML comment anywhere in the document.
-     *
-     * <p>This callback will be used for comments inside or outside the
-     * document element, including comments in the external DTD
-     * subset (if read).</p>
-     *
-     * @param ch An array holding the characters in the comment.
-     * @param start The starting position in the array.
-     * @param length The number of characters to use from the array.
-     * @exception SAXException The application may raise an exception.
-     */
-    public abstract void comment (char ch[], int start, int length)
-	throws SAXException;
-
-}
-
-// end of LexicalHandler.java
diff --git a/src/org/xml/sax/ext/Makefile b/src/org/xml/sax/ext/Makefile
deleted file mode 100644
index d2aa2fe..0000000
--- a/src/org/xml/sax/ext/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# Makefile for directory ./org/xml/sax/misc
-
-TARGETS=\
-	DeclHandler.class\
-	LexicalHandler.class
-
-DIRS =
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/xml/sax/helpers/AttributeListImpl.java b/src/org/xml/sax/helpers/AttributeListImpl.java
deleted file mode 100644
index 7a9d9c3..0000000
--- a/src/org/xml/sax/helpers/AttributeListImpl.java
+++ /dev/null
@@ -1,310 +0,0 @@
-// SAX default implementation for AttributeList.
-// No warranty; no copyright -- use this as you will.
-// $Id: AttributeListImpl.java,v 1.4 2000/05/05 17:49:14 david Exp $
-
-package org.xml.sax.helpers;
-
-import org.xml.sax.AttributeList;
-
-import java.util.Vector;
-
-
-/**
- * Default implementation for AttributeList.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>AttributeList implements the deprecated SAX1 {@link
- * org.xml.sax.AttributeList AttributeList} interface, and has been
- * replaced by the new SAX2 {@link org.xml.sax.helpers.AttributesImpl
- * AttributesImpl} interface.</p>
- *
- * <p>This class provides a convenience implementation of the SAX
- * {@link org.xml.sax.AttributeList AttributeList} interface.  This 
- * implementation is useful both for SAX parser writers, who can use 
- * it to provide attributes to the application, and for SAX application 
- * writers, who can use it to create a persistent copy of an element's 
- * attribute specifications:</p>
- *
- * <pre>
- * private AttributeList myatts;
- *
- * public void startElement (String name, AttributeList atts)
- * {
- *              // create a persistent copy of the attribute list
- *              // for use outside this method
- *   myatts = new AttributeListImpl(atts);
- *   [...]
- * }
- * </pre>
- *
- * <p>Please note that SAX parsers are not required to use this
- * class to provide an implementation of AttributeList; it is
- * supplied only as an optional convenience.  In particular, 
- * parser writers are encouraged to invent more efficient
- * implementations.</p>
- *
- * @deprecated This class implements a deprecated interface,
- *             {@link org.xml.sax.AttributeList AttributeList};
- *             that interface has been replaced by
- *             {@link org.xml.sax.Attributes Attributes},
- *             which is implemented in the
- *             {@link org.xml.sax.helpers.AttributesImpl 
- *            AttributesImpl} helper class.
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.AttributeList
- * @see org.xml.sax.DocumentHandler#startElement 
- */
-public class AttributeListImpl implements AttributeList
-{
-    
-    /**
-     * Create an empty attribute list.
-     *
-     * <p>This constructor is most useful for parser writers, who
-     * will use it to create a single, reusable attribute list that
-     * can be reset with the clear method between elements.</p>
-     *
-     * @see #addAttribute
-     * @see #clear
-     */
-    public AttributeListImpl ()
-    {
-    }
-    
-    
-    /**
-     * Construct a persistent copy of an existing attribute list.
-     *
-     * <p>This constructor is most useful for application writers,
-     * who will use it to create a persistent copy of an existing
-     * attribute list.</p>
-     *
-     * @param atts The attribute list to copy
-     * @see org.xml.sax.DocumentHandler#startElement
-     */
-    public AttributeListImpl (AttributeList atts)
-    {
-	setAttributeList(atts);
-    }
-    
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Methods specific to this class.
-    ////////////////////////////////////////////////////////////////////
-    
-    
-    /**
-     * Set the attribute list, discarding previous contents.
-     *
-     * <p>This method allows an application writer to reuse an
-     * attribute list easily.</p>
-     *
-     * @param atts The attribute list to copy.
-     */
-    public void setAttributeList (AttributeList atts)
-    {
-	int count = atts.getLength();
-	
-	clear();
-	
-	for (int i = 0; i < count; i++) {
-	    addAttribute(atts.getName(i), atts.getType(i), atts.getValue(i));
-	}
-    }
-    
-    
-    /**
-     * Add an attribute to an attribute list.
-     *
-     * <p>This method is provided for SAX parser writers, to allow them
-     * to build up an attribute list incrementally before delivering
-     * it to the application.</p>
-     *
-     * @param name The attribute name.
-     * @param type The attribute type ("NMTOKEN" for an enumeration).
-     * @param value The attribute value (must not be null).
-     * @see #removeAttribute
-     * @see org.xml.sax.DocumentHandler#startElement
-     */
-    public void addAttribute (String name, String type, String value)
-    {
-	names.addElement(name);
-	types.addElement(type);
-	values.addElement(value);
-    }
-    
-    
-    /**
-     * Remove an attribute from the list.
-     *
-     * <p>SAX application writers can use this method to filter an
-     * attribute out of an AttributeList.  Note that invoking this
-     * method will change the length of the attribute list and
-     * some of the attribute's indices.</p>
-     *
-     * <p>If the requested attribute is not in the list, this is
-     * a no-op.</p>
-     *
-     * @param name The attribute name.
-     * @see #addAttribute
-     */
-    public void removeAttribute (String name)
-    {
-	int i = names.indexOf(name);
-	
-	if (i >= 0) {
-	    names.removeElementAt(i);
-	    types.removeElementAt(i);
-	    values.removeElementAt(i);
-	}
-    }
-    
-    
-    /**
-     * Clear the attribute list.
-     *
-     * <p>SAX parser writers can use this method to reset the attribute
-     * list between DocumentHandler.startElement events.  Normally,
-     * it will make sense to reuse the same AttributeListImpl object
-     * rather than allocating a new one each time.</p>
-     *
-     * @see org.xml.sax.DocumentHandler#startElement
-     */
-    public void clear ()
-    {
-	names.removeAllElements();
-	types.removeAllElements();
-	values.removeAllElements();
-    }
-    
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Implementation of org.xml.sax.AttributeList
-    ////////////////////////////////////////////////////////////////////
-    
-    
-    /**
-     * Return the number of attributes in the list.
-     *
-     * @return The number of attributes in the list.
-     * @see org.xml.sax.AttributeList#getLength
-     */
-    public int getLength ()
-    {
-	return names.size();
-    }
-    
-    
-    /**
-     * Get the name of an attribute (by position).
-     *
-     * @param i The position of the attribute in the list.
-     * @return The attribute name as a string, or null if there
-     *         is no attribute at that position.
-     * @see org.xml.sax.AttributeList#getName(int)
-     */
-    public String getName (int i)
-    {
-	if (i < 0) {
-	    return null;
-	}
-	try {
-	    return (String)names.elementAt(i);
-	} catch (ArrayIndexOutOfBoundsException e) {
-	    return null;
-	}
-    }
-    
-    
-    /**
-     * Get the type of an attribute (by position).
-     *
-     * @param i The position of the attribute in the list.
-     * @return The attribute type as a string ("NMTOKEN" for an
-     *         enumeration, and "CDATA" if no declaration was
-     *         read), or null if there is no attribute at
-     *         that position.
-     * @see org.xml.sax.AttributeList#getType(int)
-     */
-    public String getType (int i)
-    {
-	if (i < 0) {
-	    return null;
-	}
-	try {
-	    return (String)types.elementAt(i);
-	} catch (ArrayIndexOutOfBoundsException e) {
-	    return null;
-	}
-    }
-    
-    
-    /**
-     * Get the value of an attribute (by position).
-     *
-     * @param i The position of the attribute in the list.
-     * @return The attribute value as a string, or null if
-     *         there is no attribute at that position.
-     * @see org.xml.sax.AttributeList#getValue(int)
-     */
-    public String getValue (int i)
-    {
-	if (i < 0) {
-	    return null;
-	}
-	try {
-	    return (String)values.elementAt(i);
-	} catch (ArrayIndexOutOfBoundsException e) {
-	    return null;
-	}
-    }
-    
-    
-    /**
-     * Get the type of an attribute (by name).
-     *
-     * @param name The attribute name.
-     * @return The attribute type as a string ("NMTOKEN" for an
-     *         enumeration, and "CDATA" if no declaration was
-     *         read).
-     * @see org.xml.sax.AttributeList#getType(java.lang.String)
-     */
-    public String getType (String name)
-    {
-	return getType(names.indexOf(name));
-    }
-    
-    
-    /**
-     * Get the value of an attribute (by name).
-     *
-     * @param name The attribute name.
-     * @see org.xml.sax.AttributeList#getValue(java.lang.String)
-     */
-    public String getValue (String name)
-    {
-	return getValue(names.indexOf(name));
-    }
-    
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Internal state.
-    ////////////////////////////////////////////////////////////////////
-
-    Vector names = new Vector();
-    Vector types = new Vector();
-    Vector values = new Vector();
-
-}
-
-// end of AttributeListImpl.java
diff --git a/src/org/xml/sax/helpers/AttributesImpl.java b/src/org/xml/sax/helpers/AttributesImpl.java
deleted file mode 100644
index 3763027..0000000
--- a/src/org/xml/sax/helpers/AttributesImpl.java
+++ /dev/null
@@ -1,602 +0,0 @@
-// AttributesImpl.java - default implementation of Attributes.
-// Written by David Megginson, sax@megginson.com
-// NO WARRANTY!  This class is in the public domain.
-
-// $Id: AttributesImpl.java,v 1.4 2000/05/05 17:49:22 david Exp $
-
-
-package org.xml.sax.helpers;
-
-import org.xml.sax.Attributes;
-
-
-/**
- * Default implementation of the Attributes interface.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This class provides a default implementation of the SAX2
- * {@link org.xml.sax.Attributes Attributes} interface, with the 
- * addition of manipulators so that the list can be modified or 
- * reused.</p>
- *
- * <p>There are two typical uses of this class:</p>
- *
- * <ol>
- * <li>to take a persistent snapshot of an Attributes object
- *  in a {@link org.xml.sax.ContentHandler#startElement startElement} event; or</li>
- * <li>to construct or modify an Attributes object in a SAX2 driver or filter.</li>
- * </ol>
- *
- * <p>This class replaces the now-deprecated SAX1 {@link 
- * org.xml.sax.helpers.AttributeListImpl AttributeListImpl}
- * class; in addition to supporting the updated Attributes
- * interface rather than the deprecated {@link org.xml.sax.AttributeList
- * AttributeList} interface, it also includes a much more efficient 
- * implementation using a single array rather than a set of Vectors.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- */
-public class AttributesImpl implements Attributes
-{
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Constructors.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Construct a new, empty AttributesImpl object.
-     */
-    public AttributesImpl ()
-    {
-	length = 0;
-	data = null;
-    }
-
-
-    /**
-     * Copy an existing Attributes object.
-     *
-     * <p>This constructor is especially useful inside a
-     * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p>
-     *
-     * @param atts The existing Attributes object.
-     */
-    public AttributesImpl (Attributes atts)
-    {
-	setAttributes(atts);
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Implementation of org.xml.sax.Attributes.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Return the number of attributes in the list.
-     *
-     * @return The number of attributes in the list.
-     * @see org.xml.sax.Attributes#getLength
-     */
-    public int getLength ()
-    {
-	return length;
-    }
-
-
-    /**
-     * Return an attribute's Namespace URI.
-     *
-     * @param index The attribute's index (zero-based).
-     * @return The Namespace URI, the empty string if none is
-     *         available, or null if the index is out of range.
-     * @see org.xml.sax.Attributes#getURI
-     */
-    public String getURI (int index)
-    {
-	if (index >= 0 && index < length) {
-	    return data[index*5];
-	} else {
-	    return null;
-	}
-    }
-
-
-    /**
-     * Return an attribute's local name.
-     *
-     * @param index The attribute's index (zero-based).
-     * @return The attribute's local name, the empty string if 
-     *         none is available, or null if the index if out of range.
-     * @see org.xml.sax.Attributes#getLocalName
-     */
-    public String getLocalName (int index)
-    {
-	if (index >= 0 && index < length) {
-	    return data[index*5+1];
-	} else {
-	    return null;
-	}
-    }
-
-
-    /**
-     * Return an attribute's qualified (prefixed) name.
-     *
-     * @param index The attribute's index (zero-based).
-     * @return The attribute's qualified name, the empty string if 
-     *         none is available, or null if the index is out of bounds.
-     * @see org.xml.sax.Attributes#getQName
-     */
-    public String getQName (int index)
-    {
-	if (index >= 0 && index < length) {
-	    return data[index*5+2];
-	} else {
-	    return null;
-	}
-    }
-
-
-    /**
-     * Return an attribute's type by index.
-     *
-     * @param index The attribute's index (zero-based).
-     * @return The attribute's type, "CDATA" if the type is unknown, or null
-     *         if the index is out of bounds.
-     * @see org.xml.sax.Attributes#getType(int)
-     */
-    public String getType (int index)
-    {
-	if (index >= 0 && index < length) {
-	    return data[index*5+3];
-	} else {
-	    return null;
-	}
-    }
-
-
-    /**
-     * Return an attribute's value by index.
-     *
-     * @param index The attribute's index (zero-based).
-     * @return The attribute's value or null if the index is out of bounds.
-     * @see org.xml.sax.Attributes#getValue(int)
-     */
-    public String getValue (int index)
-    {
-	if (index >= 0 && index < length) {
-	    return data[index*5+4];
-	} else {
-	    return null;
-	}
-    }
-
-
-    /**
-     * Look up an attribute's index by Namespace name.
-     *
-     * <p>In many cases, it will be more efficient to look up the name once and
-     * use the index query methods rather than using the name query methods
-     * repeatedly.</p>
-     *
-     * @param uri The attribute's Namespace URI, or the empty
-     *        string if none is available.
-     * @param localName The attribute's local name.
-     * @return The attribute's index, or -1 if none matches.
-     * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String)
-     */
-    public int getIndex (String uri, String localName)
-    {
-	int max = length * 5;
-	for (int i = 0; i < max; i += 5) {
-	    if (data[i].equals(uri) && data[i+1].equals(localName)) {
-		return i / 5;
-	    }
-	} 
-	return -1;
-    }
-
-
-    /**
-     * Look up an attribute's index by qualified (prefixed) name.
-     *
-     * @param qName The qualified name.
-     * @return The attribute's index, or -1 if none matches.
-     * @see org.xml.sax.Attributes#getIndex(java.lang.String)
-     */
-    public int getIndex (String qName)
-    {
-	int max = length * 5;
-	for (int i = 0; i < max; i += 5) {
-	    if (data[i+2].equals(qName)) {
-		return i / 5;
-	    }
-	} 
-	return -1;
-    }
-
-
-    /**
-     * Look up an attribute's type by Namespace-qualified name.
-     *
-     * @param uri The Namespace URI, or the empty string for a name
-     *        with no explicit Namespace URI.
-     * @param localName The local name.
-     * @return The attribute's type, or null if there is no
-     *         matching attribute.
-     * @see org.xml.sax.Attributes#getType(java.lang.String,java.lang.String)
-     */
-    public String getType (String uri, String localName)
-    {
-	int max = length * 5;
-	for (int i = 0; i < max; i += 5) {
-	    if (data[i].equals(uri) && data[i+1].equals(localName)) {
-		return data[i+3];
-	    }
-	} 
-	return null;
-    }
-
-
-    /**
-     * Look up an attribute's type by qualified (prefixed) name.
-     *
-     * @param qName The qualified name.
-     * @return The attribute's type, or null if there is no
-     *         matching attribute.
-     * @see org.xml.sax.Attributes#getType(java.lang.String)
-     */
-    public String getType (String qName)
-    {
-	int max = length * 5;
-	for (int i = 0; i < max; i += 5) {
-	    if (data[i+2].equals(qName)) {
-		return data[i+3];
-	    }
-	}
-	return null;
-    }
-
-
-    /**
-     * Look up an attribute's value by Namespace-qualified name.
-     *
-     * @param uri The Namespace URI, or the empty string for a name
-     *        with no explicit Namespace URI.
-     * @param localName The local name.
-     * @return The attribute's value, or null if there is no
-     *         matching attribute.
-     * @see org.xml.sax.Attributes#getValue(java.lang.String,java.lang.String)
-     */
-    public String getValue (String uri, String localName)
-    {
-	int max = length * 5;
-	for (int i = 0; i < max; i += 5) {
-	    if (data[i].equals(uri) && data[i+1].equals(localName)) {
-		return data[i+4];
-	    }
-	}
-	return null;
-    }
-
-
-    /**
-     * Look up an attribute's value by qualified (prefixed) name.
-     *
-     * @param qName The qualified name.
-     * @return The attribute's value, or null if there is no
-     *         matching attribute.
-     * @see org.xml.sax.Attributes#getValue(java.lang.String)
-     */
-    public String getValue (String qName)
-    {
-	int max = length * 5;
-	for (int i = 0; i < max; i += 5) {
-	    if (data[i+2].equals(qName)) {
-		return data[i+4];
-	    }
-	}
-	return null;
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Manipulators.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Clear the attribute list for reuse.
-     *
-     * <p>Note that no memory is actually freed by this call:
-     * the current arrays are kept so that they can be 
-     * reused.</p>
-     */
-    public void clear ()
-    {
-	length = 0;
-    }
-
-
-    /**
-     * Copy an entire Attributes object.
-     *
-     * <p>It may be more efficient to reuse an existing object
-     * rather than constantly allocating new ones.</p>
-     * 
-     * @param atts The attributes to copy.
-     */
-    public void setAttributes (Attributes atts)
-    {
-	clear();
-	length = atts.getLength();
-	data = new String[length*5]; 
-	for (int i = 0; i < length; i++) {
-	    data[i*5] = atts.getURI(i);
-	    data[i*5+1] = atts.getLocalName(i);
-	    data[i*5+2] = atts.getQName(i);
-	    data[i*5+3] = atts.getType(i);
-	    data[i*5+4] = atts.getValue(i);
-	}
-    }
-
-
-    /**
-     * Add an attribute to the end of the list.
-     *
-     * <p>For the sake of speed, this method does no checking
-     * to see if the attribute is already in the list: that is
-     * the responsibility of the application.</p>
-     *
-     * @param uri The Namespace URI, or the empty string if
-     *        none is available or Namespace processing is not
-     *        being performed.
-     * @param localName The local name, or the empty string if
-     *        Namespace processing is not being performed.
-     * @param qName The qualified (prefixed) name, or the empty string
-     *        if qualified names are not available.
-     * @param type The attribute type as a string.
-     * @param value The attribute value.
-     */
-    public void addAttribute (String uri, String localName, String qName,
-			      String type, String value)
-    {
-	ensureCapacity(length+1);
-	data[length*5] = uri;
-	data[length*5+1] = localName;
-	data[length*5+2] = qName;
-	data[length*5+3] = type;
-	data[length*5+4] = value;
-	length++;
-    }
-
-
-    /**
-     * Set an attribute in the list.
-     *
-     * <p>For the sake of speed, this method does no checking
-     * for name conflicts or well-formedness: such checks are the
-     * responsibility of the application.</p>
-     *
-     * @param index The index of the attribute (zero-based).
-     * @param uri The Namespace URI, or the empty string if
-     *        none is available or Namespace processing is not
-     *        being performed.
-     * @param localName The local name, or the empty string if
-     *        Namespace processing is not being performed.
-     * @param qName The qualified name, or the empty string
-     *        if qualified names are not available.
-     * @param type The attribute type as a string.
-     * @param value The attribute value.
-     * @exception java.lang.ArrayIndexOutOfBoundsException When the
-     *            supplied index does not point to an attribute
-     *            in the list.
-     */
-    public void setAttribute (int index, String uri, String localName,
-			      String qName, String type, String value)
-    {
-	if (index >= 0 && index < length) {
-	    data[index*5] = uri;
-	    data[index*5+1] = localName;
-	    data[index*5+2] = qName;
-	    data[index*5+3] = type;
-	    data[index*5+4] = value;
-	} else {
-	    badIndex(index);
-	}
-    }
-
-
-    /**
-     * Remove an attribute from the list.
-     *
-     * @param index The index of the attribute (zero-based).
-     * @exception java.lang.ArrayIndexOutOfBoundsException When the
-     *            supplied index does not point to an attribute
-     *            in the list.
-     */
-    public void removeAttribute (int index)
-    {
-	if (index >= 0 && index < length) {
-	    data[index] = null;
-	    if (index < length - 1) {
-		System.arraycopy(data, (index+1)*5, data, index*5,
-				 (length-index)*5);
-	    }
-	    length--;
-	} else {
-	    badIndex(index);
-	}
-    }
-
-
-    /**
-     * Set the Namespace URI of a specific attribute.
-     *
-     * @param index The index of the attribute (zero-based).
-     * @param uri The attribute's Namespace URI, or the empty
-     *        string for none.
-     * @exception java.lang.ArrayIndexOutOfBoundsException When the
-     *            supplied index does not point to an attribute
-     *            in the list.
-     */
-    public void setURI (int index, String uri)
-    {
-	if (index >= 0 && index < length) {
-	    data[index*5] = uri;
-	} else {
-	    badIndex(index);
-	}
-    }
-
-
-    /**
-     * Set the local name of a specific attribute.
-     *
-     * @param index The index of the attribute (zero-based).
-     * @param localName The attribute's local name, or the empty
-     *        string for none.
-     * @exception java.lang.ArrayIndexOutOfBoundsException When the
-     *            supplied index does not point to an attribute
-     *            in the list.
-     */
-    public void setLocalName (int index, String localName)
-    {
-	if (index >= 0 && index < length) {
-	    data[index*5+1] = localName;
-	} else {
-	    badIndex(index);
-	}
-    }
-
-
-    /**
-     * Set the qualified name of a specific attribute.
-     *
-     * @param index The index of the attribute (zero-based).
-     * @param qName The attribute's qualified name, or the empty
-     *        string for none.
-     * @exception java.lang.ArrayIndexOutOfBoundsException When the
-     *            supplied index does not point to an attribute
-     *            in the list.
-     */
-    public void setQName (int index, String qName)
-    {
-	if (index >= 0 && index < length) {
-	    data[index*5+2] = qName;
-	} else {
-	    badIndex(index);
-	}
-    }
-
-
-    /**
-     * Set the type of a specific attribute.
-     *
-     * @param index The index of the attribute (zero-based).
-     * @param type The attribute's type.
-     * @exception java.lang.ArrayIndexOutOfBoundsException When the
-     *            supplied index does not point to an attribute
-     *            in the list.
-     */
-    public void setType (int index, String type)
-    {
-	if (index >= 0 && index < length) {
-	    data[index*5+3] = type;
-	} else {
-	    badIndex(index);
-	}
-    }
-
-
-    /**
-     * Set the value of a specific attribute.
-     *
-     * @param index The index of the attribute (zero-based).
-     * @param value The attribute's value.
-     * @exception java.lang.ArrayIndexOutOfBoundsException When the
-     *            supplied index does not point to an attribute
-     *            in the list.
-     */
-    public void setValue (int index, String value)
-    {
-	if (index >= 0 && index < length) {
-	    data[index*5+4] = value;
-	} else {
-	    badIndex(index);
-	}
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Internal methods.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Ensure the internal array's capacity.
-     *
-     * @param n The minimum number of attributes that the array must
-     *        be able to hold.
-     */
-    private void ensureCapacity (int n)
-    {
-	if (n > 0 && data == null) {
-	    data = new String[25];
-	}
-
-	int max = data.length;
-	if (max >= n * 5) {
-	    return;
-	}
-
-
-	while (max < n * 5) {
-	    max *= 2;
-	}
-	String newData[] = new String[max];
-	System.arraycopy(data, 0, newData, 0, length*5);
-	data = newData;
-    }
-
-
-    /**
-     * Report a bad array index in a manipulator.
-     *
-     * @param index The index to report.
-     * @exception java.lang.ArrayIndexOutOfBoundsException Always.
-     */
-    private void badIndex (int index)
-	throws ArrayIndexOutOfBoundsException
-    {
-	String msg =
-	    "Attempt to modify attribute at illegal index: " + index;
-	throw new ArrayIndexOutOfBoundsException(msg);
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Internal state.
-    ////////////////////////////////////////////////////////////////////
-
-    int length;
-    String data [];
-
-}
-
-// end of AttributesImpl.java
-
diff --git a/src/org/xml/sax/helpers/DefaultHandler.java b/src/org/xml/sax/helpers/DefaultHandler.java
deleted file mode 100644
index b3b24f0..0000000
--- a/src/org/xml/sax/helpers/DefaultHandler.java
+++ /dev/null
@@ -1,447 +0,0 @@
-// DefaultHandler.java - default implementation of the core handlers.
-// Written by David Megginson, sax@megginson.com
-// NO WARRANTY!  This class is in the public domain.
-
-// $Id: DefaultHandler.java,v 1.3 2000/05/05 17:49:33 david Exp $
-
-package org.xml.sax.helpers;
-
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import org.xml.sax.Attributes;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.DTDHandler;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-
-/**
- * Default base class for SAX2 event handlers.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This class is available as a convenience base class for SAX2
- * applications: it provides default implementations for all of the
- * callbacks in the four core SAX2 handler classes:</p>
- *
- * <ul>
- * <li>{@link org.xml.sax.EntityResolver EntityResolver}</li>
- * <li>{@link org.xml.sax.DTDHandler DTDHandler}</li>
- * <li>{@link org.xml.sax.ContentHandler ContentHandler}</li>
- * <li>{@link org.xml.sax.ErrorHandler ErrorHandler}</li>
- * </ul>
- *
- * <p>Application writers can extend this class when they need to
- * implement only part of an interface; parser writers can
- * instantiate this class to provide default handlers when the
- * application has not supplied its own.</p>
- *
- * <p>This class replaces the deprecated SAX1
- * {@link org.xml.sax.HandlerBase HandlerBase} class.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.EntityResolver
- * @see org.xml.sax.DTDHandler
- * @see org.xml.sax.ContentHandler
- * @see org.xml.sax.ErrorHandler
- */
-public class DefaultHandler
-    implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler
-{
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Default implementation of the EntityResolver interface.
-    ////////////////////////////////////////////////////////////////////
-    
-    /**
-     * Resolve an external entity.
-     *
-     * <p>Always return null, so that the parser will use the system
-     * identifier provided in the XML document.  This method implements
-     * the SAX default behaviour: application writers can override it
-     * in a subclass to do special translations such as catalog lookups
-     * or URI redirection.</p>
-     *
-     * @param publicId The public identifer, or null if none is
-     *                 available.
-     * @param systemId The system identifier provided in the XML 
-     *                 document.
-     * @return The new input source, or null to require the
-     *         default behaviour.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.EntityResolver#resolveEntity
-     */
-    public InputSource resolveEntity (String publicId, String systemId)
-	throws SAXException
-    {
-	return null;
-    }
-    
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Default implementation of DTDHandler interface.
-    ////////////////////////////////////////////////////////////////////
-    
-    
-    /**
-     * Receive notification of a notation declaration.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass if they wish to keep track of the notations
-     * declared in a document.</p>
-     *
-     * @param name The notation name.
-     * @param publicId The notation public identifier, or null if not
-     *                 available.
-     * @param systemId The notation system identifier.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.DTDHandler#notationDecl
-     */
-    public void notationDecl (String name, String publicId, String systemId)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of an unparsed entity declaration.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to keep track of the unparsed entities
-     * declared in a document.</p>
-     *
-     * @param name The entity name.
-     * @param publicId The entity public identifier, or null if not
-     *                 available.
-     * @param systemId The entity system identifier.
-     * @param notationName The name of the associated notation.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.DTDHandler#unparsedEntityDecl
-     */
-    public void unparsedEntityDecl (String name, String publicId,
-				    String systemId, String notationName)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Default implementation of ContentHandler interface.
-    ////////////////////////////////////////////////////////////////////
-    
-    
-    /**
-     * Receive a Locator object for document events.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass if they wish to store the locator for use
-     * with other document events.</p>
-     *
-     * @param locator A locator for all SAX document events.
-     * @see org.xml.sax.ContentHandler#setDocumentLocator
-     * @see org.xml.sax.Locator
-     */
-    public void setDocumentLocator (Locator locator)
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of the beginning of the document.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to take specific actions at the beginning
-     * of a document (such as allocating the root node of a tree or
-     * creating an output file).</p>
-     *
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ContentHandler#startDocument
-     */
-    public void startDocument ()
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of the end of the document.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to take specific actions at the end
-     * of a document (such as finalising a tree or closing an output
-     * file).</p>
-     *
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ContentHandler#endDocument
-     */
-    public void endDocument ()
-	throws SAXException
-    {
-	// no op
-    }
-
-
-    /**
-     * Receive notification of the start of a Namespace mapping.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to take specific actions at the start of
-     * each Namespace prefix scope (such as storing the prefix mapping).</p>
-     *
-     * @param prefix The Namespace prefix being declared.
-     * @param uri The Namespace URI mapped to the prefix.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ContentHandler#startPrefixMapping
-     */
-    public void startPrefixMapping (String prefix, String uri)
-	throws SAXException
-    {
-	// no op
-    }
-
-
-    /**
-     * Receive notification of the end of a Namespace mapping.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to take specific actions at the end of
-     * each prefix mapping.</p>
-     *
-     * @param prefix The Namespace prefix being declared.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ContentHandler#endPrefixMapping
-     */
-    public void endPrefixMapping (String prefix)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of the start of an element.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to take specific actions at the start of
-     * each element (such as allocating a new tree node or writing
-     * output to a file).</p>
-     *
-     * @param name The element type name.
-     * @param attributes The specified or defaulted attributes.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ContentHandler#startElement
-     */
-    public void startElement (String uri, String localName,
-			      String qName, Attributes attributes)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of the end of an element.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to take specific actions at the end of
-     * each element (such as finalising a tree node or writing
-     * output to a file).</p>
-     *
-     * @param name The element type name.
-     * @param attributes The specified or defaulted attributes.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ContentHandler#endElement
-     */
-    public void endElement (String uri, String localName, String qName)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of character data inside an element.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method to take specific actions for each chunk of character data
-     * (such as adding the data to a node or buffer, or printing it to
-     * a file).</p>
-     *
-     * @param ch The characters.
-     * @param start The start position in the character array.
-     * @param length The number of characters to use from the
-     *               character array.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ContentHandler#characters
-     */
-    public void characters (char ch[], int start, int length)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of ignorable whitespace in element content.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method to take specific actions for each chunk of ignorable
-     * whitespace (such as adding data to a node or buffer, or printing
-     * it to a file).</p>
-     *
-     * @param ch The whitespace characters.
-     * @param start The start position in the character array.
-     * @param length The number of characters to use from the
-     *               character array.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ContentHandler#ignorableWhitespace
-     */
-    public void ignorableWhitespace (char ch[], int start, int length)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of a processing instruction.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to take specific actions for each
-     * processing instruction, such as setting status variables or
-     * invoking other methods.</p>
-     *
-     * @param target The processing instruction target.
-     * @param data The processing instruction data, or null if
-     *             none is supplied.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ContentHandler#processingInstruction
-     */
-    public void processingInstruction (String target, String data)
-	throws SAXException
-    {
-	// no op
-    }
-
-
-    /**
-     * Receive notification of a skipped entity.
-     *
-     * <p>By default, do nothing.  Application writers may override this
-     * method in a subclass to take specific actions for each
-     * processing instruction, such as setting status variables or
-     * invoking other methods.</p>
-     *
-     * @param name The name of the skipped entity.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ContentHandler#processingInstruction
-     */
-    public void skippedEntity (String name)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Default implementation of the ErrorHandler interface.
-    ////////////////////////////////////////////////////////////////////
-    
-    
-    /**
-     * Receive notification of a parser warning.
-     *
-     * <p>The default implementation does nothing.  Application writers
-     * may override this method in a subclass to take specific actions
-     * for each warning, such as inserting the message in a log file or
-     * printing it to the console.</p>
-     *
-     * @param e The warning information encoded as an exception.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ErrorHandler#warning
-     * @see org.xml.sax.SAXParseException
-     */
-    public void warning (SAXParseException e)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Receive notification of a recoverable parser error.
-     *
-     * <p>The default implementation does nothing.  Application writers
-     * may override this method in a subclass to take specific actions
-     * for each error, such as inserting the message in a log file or
-     * printing it to the console.</p>
-     *
-     * @param e The warning information encoded as an exception.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ErrorHandler#warning
-     * @see org.xml.sax.SAXParseException
-     */
-    public void error (SAXParseException e)
-	throws SAXException
-    {
-	// no op
-    }
-    
-    
-    /**
-     * Report a fatal XML parsing error.
-     *
-     * <p>The default implementation throws a SAXParseException.
-     * Application writers may override this method in a subclass if
-     * they need to take specific actions for each fatal error (such as
-     * collecting all of the errors into a single report): in any case,
-     * the application must stop all regular processing when this
-     * method is invoked, since the document is no longer reliable, and
-     * the parser may no longer report parsing events.</p>
-     *
-     * @param e The error information encoded as an exception.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.ErrorHandler#fatalError
-     * @see org.xml.sax.SAXParseException
-     */
-    public void fatalError (SAXParseException e)
-	throws SAXException
-    {
-	throw e;
-    }
-    
-}
-
-// end of DefaultHandler.java
diff --git a/src/org/xml/sax/helpers/LocatorImpl.java b/src/org/xml/sax/helpers/LocatorImpl.java
deleted file mode 100644
index cf4d7ef..0000000
--- a/src/org/xml/sax/helpers/LocatorImpl.java
+++ /dev/null
@@ -1,212 +0,0 @@
-// SAX default implementation for Locator.
-// No warranty; no copyright -- use this as you will.
-// $Id: LocatorImpl.java,v 1.4 2000/05/05 17:49:44 david Exp $
-
-package org.xml.sax.helpers;
-
-import org.xml.sax.Locator;
-
-
-/**
- * Provide an optional convenience implementation of Locator.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This class is available mainly for application writers, who
- * can use it to make a persistent snapshot of a locator at any
- * point during a document parse:</p>
- *
- * <pre>
- * Locator locator;
- * Locator startloc;
- *
- * public void setLocator (Locator locator)
- * {
- *         // note the locator
- *   this.locator = locator;
- * }
- *
- * public void startDocument ()
- * {
- *         // save the location of the start of the document
- *         // for future use.
- *   Locator startloc = new LocatorImpl(locator);
- * }
- *</pre>
- *
- * <p>Normally, parser writers will not use this class, since it
- * is more efficient to provide location information only when
- * requested, rather than constantly updating a Locator object.</p>
- *
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.Locator Locator
- */
-public class LocatorImpl implements Locator
-{
-    
-    
-    /**
-     * Zero-argument constructor.
-     *
-     * <p>This will not normally be useful, since the main purpose
-     * of this class is to make a snapshot of an existing Locator.</p>
-     */
-    public LocatorImpl ()
-    {
-    }
-    
-    
-    /**
-     * Copy constructor.
-     *
-     * <p>Create a persistent copy of the current state of a locator.
-     * When the original locator changes, this copy will still keep
-     * the original values (and it can be used outside the scope of
-     * DocumentHandler methods).</p>
-     *
-     * @param locator The locator to copy.
-     */
-    public LocatorImpl (Locator locator)
-    {
-	setPublicId(locator.getPublicId());
-	setSystemId(locator.getSystemId());
-	setLineNumber(locator.getLineNumber());
-	setColumnNumber(locator.getColumnNumber());
-    }
-    
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Implementation of org.xml.sax.Locator
-    ////////////////////////////////////////////////////////////////////
-    
-    
-    /**
-     * Return the saved public identifier.
-     *
-     * @return The public identifier as a string, or null if none
-     *         is available.
-     * @see org.xml.sax.Locator#getPublicId
-     * @see #setPublicId
-     */
-    public String getPublicId ()
-    {
-	return publicId;
-    }
-    
-    
-    /**
-     * Return the saved system identifier.
-     *
-     * @return The system identifier as a string, or null if none
-     *         is available.
-     * @see org.xml.sax.Locator#getSystemId
-     * @see #setSystemId
-     */
-    public String getSystemId ()
-    {
-	return systemId;
-    }
-    
-    
-    /**
-     * Return the saved line number (1-based).
-     *
-     * @return The line number as an integer, or -1 if none is available.
-     * @see org.xml.sax.Locator#getLineNumber
-     * @see #setLineNumber
-     */
-    public int getLineNumber ()
-    {
-	return lineNumber;
-    }
-    
-    
-    /**
-     * Return the saved column number (1-based).
-     *
-     * @return The column number as an integer, or -1 if none is available.
-     * @see org.xml.sax.Locator#getColumnNumber
-     * @see #setColumnNumber
-     */
-    public int getColumnNumber ()
-    {
-	return columnNumber;
-    }
-    
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Setters for the properties (not in org.xml.sax.Locator)
-    ////////////////////////////////////////////////////////////////////
-    
-    
-    /**
-     * Set the public identifier for this locator.
-     *
-     * @param publicId The new public identifier, or null 
-     *        if none is available.
-     * @see #getPublicId
-     */
-    public void setPublicId (String publicId)
-    {
-	this.publicId = publicId;
-    }
-    
-    
-    /**
-     * Set the system identifier for this locator.
-     *
-     * @param systemId The new system identifier, or null 
-     *        if none is available.
-     * @see #getSystemId
-     */
-    public void setSystemId (String systemId)
-    {
-	this.systemId = systemId;
-    }
-    
-    
-    /**
-     * Set the line number for this locator (1-based).
-     *
-     * @param lineNumber The line number, or -1 if none is available.
-     * @see #getLineNumber
-     */
-    public void setLineNumber (int lineNumber)
-    {
-	this.lineNumber = lineNumber;
-    }
-    
-    
-    /**
-     * Set the column number for this locator (1-based).
-     *
-     * @param columnNumber The column number, or -1 if none is available.
-     * @see #getColumnNumber
-     */
-    public void setColumnNumber (int columnNumber)
-    {
-	this.columnNumber = columnNumber;
-    }
-    
-    
-
-    ////////////////////////////////////////////////////////////////////
-    // Internal state.
-    ////////////////////////////////////////////////////////////////////
-    
-    private String publicId;
-    private String systemId;
-    private int lineNumber;
-    private int columnNumber;
-    
-}
-
-// end of LocatorImpl.java
diff --git a/src/org/xml/sax/helpers/Makefile b/src/org/xml/sax/helpers/Makefile
deleted file mode 100644
index 97cca39..0000000
--- a/src/org/xml/sax/helpers/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-# Makefile for directory ./org/xml/sax/helpers
-
-TARGETS=\
-	AttributesImpl.class\
-	AttributeListImpl.class\
-	DefaultHandler.class\
-	LocatorImpl.class\
-	NamespaceSupport.class\
-	ParserAdapter.class\
-	ParserFactory.class\
-	XMLFilterImpl.class\
-	XMLReaderAdapter.class\
-	XMLReaderFactory.class
-
-DIRS =
-
-TOP = ../../../../..
-include $(TOP)/src/Makefile.incl
diff --git a/src/org/xml/sax/helpers/NamespaceSupport.java b/src/org/xml/sax/helpers/NamespaceSupport.java
deleted file mode 100644
index 9937479..0000000
--- a/src/org/xml/sax/helpers/NamespaceSupport.java
+++ /dev/null
@@ -1,689 +0,0 @@
-// NamespaceSupport.java - generic Namespace support for SAX.
-// Written by David Megginson, sax@megginson.com
-// This class is in the Public Domain.  NO WARRANTY!
-
-// $Id: NamespaceSupport.java,v 1.8 2000/05/05 17:49:53 david Exp $
-
-package org.xml.sax.helpers;
-
-import java.util.EmptyStackException;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
-
-
-/**
- * Encapsulate Namespace logic for use by SAX drivers.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This class encapsulates the logic of Namespace processing:
- * it tracks the declarations currently in force for each context
- * and automatically processes qualified XML 1.0 names into their
- * Namespace parts; it can also be used in reverse for generating
- * XML 1.0 from Namespaces.</p>
- *
- * <p>Namespace support objects are reusable, but the reset method
- * must be invoked between each session.</p>
- *
- * <p>Here is a simple session:</p>
- *
- * <pre>
- * String parts[] = new String[3];
- * NamespaceSupport support = new NamespaceSupport();
- *
- * support.pushContext();
- * support.declarePrefix("", "http://www.w3.org/1999/xhtml");
- * support.declarePrefix("dc", "http://www.purl.org/dc#");
- *
- * String parts[] = support.processName("p", parts, false);
- * System.out.println("Namespace URI: " + parts[0]);
- * System.out.println("Local name: " + parts[1]);
- * System.out.println("Raw name: " + parts[2]);
-
- * String parts[] = support.processName("dc:title", parts, false);
- * System.out.println("Namespace URI: " + parts[0]);
- * System.out.println("Local name: " + parts[1]);
- * System.out.println("Raw name: " + parts[2]);
-
- * support.popContext();
- * </pre>
- *
- * <p>Note that this class is optimized for the use case where most
- * elements do not contain Namespace declarations: if the same
- * prefix/URI mapping is repeated for each context (for example), this
- * class will be somewhat less efficient.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- */
-public class NamespaceSupport
-{
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Constants.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * The XML Namespace as a constant.
-     *
-     * <p>This is the Namespace URI that is automatically mapped
-     * to the "xml" prefix.</p>
-     */
-    public final static String XMLNS =
-	"http://www.w3.org/XML/1998/namespace";
-
-
-    /**
-     * An empty enumeration.
-     */
-    private final static Enumeration EMPTY_ENUMERATION =
-	new Vector().elements();
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Constructor.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Create a new Namespace support object.
-     */
-    public NamespaceSupport ()
-    {
-	reset();
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Context management.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Reset this Namespace support object for reuse.
-     *
-     * <p>It is necessary to invoke this method before reusing the
-     * Namespace support object for a new session.</p>
-     */
-    public void reset ()
-    {
-	contexts = new Context[32];
-	contextPos = 0;
-	contexts[contextPos] = currentContext = new Context();
-	currentContext.declarePrefix("xml", XMLNS);
-    }
-
-
-    /**
-     * Start a new Namespace context.
-     *
-     * <p>Normally, you should push a new context at the beginning
-     * of each XML element: the new context will automatically inherit
-     * the declarations of its parent context, but it will also keep
-     * track of which declarations were made within this context.</p>
-     *
-     * <p>The Namespace support object always starts with a base context
-     * already in force: in this context, only the "xml" prefix is
-     * declared.</p>
-     *
-     * @see #popContext
-     */
-    public void pushContext ()
-    {
-	int max = contexts.length;
-	contextPos++;
-
-				// Extend the array if necessary
-	if (contextPos >= max) {
-	    Context newContexts[] = new Context[max*2];
-	    System.arraycopy(contexts, 0, newContexts, 0, max);
-	    max *= 2;
-	    contexts = newContexts;
-	}
-
-				// Allocate the context if necessary.
-	currentContext = contexts[contextPos];
-	if (currentContext == null) {
-	    contexts[contextPos] = currentContext = new Context();
-	}
-
-				// Set the parent, if any.
-	if (contextPos > 0) {
-	    currentContext.setParent(contexts[contextPos - 1]);
-	}
-    }
-
-
-    /**
-     * Revert to the previous Namespace context.
-     *
-     * <p>Normally, you should pop the context at the end of each
-     * XML element.  After popping the context, all Namespace prefix
-     * mappings that were previously in force are restored.</p>
-     *
-     * <p>You must not attempt to declare additional Namespace
-     * prefixes after popping a context, unless you push another
-     * context first.</p>
-     *
-     * @see #pushContext
-     */
-    public void popContext ()
-    {
-	contextPos--;
-	if (contextPos < 0) {
-	    throw new EmptyStackException();
-	}
-	currentContext = contexts[contextPos];
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Operations within a context.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Declare a Namespace prefix.
-     *
-     * <p>This method declares a prefix in the current Namespace
-     * context; the prefix will remain in force until this context
-     * is popped, unless it is shadowed in a descendant context.</p>
-     *
-     * <p>To declare a default Namespace, use the empty string.  The
-     * prefix must not be "xml" or "xmlns".</p>
-     *
-     * <p>Note that you must <em>not</em> declare a prefix after
-     * you've pushed and popped another Namespace.</p>
-     *
-     * <p>Note that there is an asymmetry in this library: while {@link
-     * #getPrefix getPrefix} will not return the default "" prefix,
-     * even if you have declared one; to check for a default prefix,
-     * you have to look it up explicitly using {@link #getURI getURI}.
-     * This asymmetry exists to make it easier to look up prefixes
-     * for attribute names, where the default prefix is not allowed.</p>
-     *
-     * @param prefix The prefix to declare, or null for the empty
-     *        string.
-     * @param uri The Namespace URI to associate with the prefix.
-     * @return true if the prefix was legal, false otherwise
-     * @see #processName
-     * @see #getURI
-     * @see #getPrefix
-     */
-    public boolean declarePrefix (String prefix, String uri)
-    {
-	if (prefix.equals("xml") || prefix.equals("xmlns")) {
-	    return false;
-	} else {
-	    currentContext.declarePrefix(prefix, uri);
-	    return true;
-	}
-    }
-
-
-    /**
-     * Process a raw XML 1.0 name.
-     *
-     * <p>This method processes a raw XML 1.0 name in the current
-     * context by removing the prefix and looking it up among the
-     * prefixes currently declared.  The return value will be the
-     * array supplied by the caller, filled in as follows:</p>
-     *
-     * <dl>
-     * <dt>parts[0]</dt>
-     * <dd>The Namespace URI, or an empty string if none is
-     *  in use.</dd>
-     * <dt>parts[1]</dt>
-     * <dd>The local name (without prefix).</dd>
-     * <dt>parts[2]</dt>
-     * <dd>The original raw name.</dd>
-     * </dl>
-     *
-     * <p>All of the strings in the array will be internalized.  If
-     * the raw name has a prefix that has not been declared, then
-     * the return value will be null.</p>
-     *
-     * <p>Note that attribute names are processed differently than
-     * element names: an unprefixed element name will received the
-     * default Namespace (if any), while an unprefixed element name
-     * will not.</p>
-     *
-     * @param qName The raw XML 1.0 name to be processed.
-     * @param parts An array supplied by the caller, capable of
-     *        holding at least three members.
-     * @param isAttribute A flag indicating whether this is an
-     *        attribute name (true) or an element name (false).
-     * @return The supplied array holding three internalized strings 
-     *        representing the Namespace URI (or empty string), the
-     *        local name, and the raw XML 1.0 name; or null if there
-     *        is an undeclared prefix.
-     * @see #declarePrefix
-     * @see java.lang.String#intern */
-    public String [] processName (String qName, String parts[],
-				  boolean isAttribute)
-    {
-	String myParts[] = currentContext.processName(qName, isAttribute);
-	if (myParts == null) {
-	    return null;
-	} else {
-	    parts[0] = myParts[0];
-	    parts[1] = myParts[1];
-	    parts[2] = myParts[2];
-	    return parts;
-	}
-    }
-
-
-    /**
-     * Look up a prefix and get the currently-mapped Namespace URI.
-     *
-     * <p>This method looks up the prefix in the current context.
-     * Use the empty string ("") for the default Namespace.</p>
-     *
-     * @param prefix The prefix to look up.
-     * @return The associated Namespace URI, or null if the prefix
-     *         is undeclared in this context.
-     * @see #getPrefix
-     * @see #getPrefixes
-     */
-    public String getURI (String prefix)
-    {
-	return currentContext.getURI(prefix);
-    }
-
-
-    /**
-     * Return an enumeration of all prefixes currently declared.
-     *
-     * <p><strong>Note:</strong> if there is a default prefix, it will not be
-     * returned in this enumeration; check for the default prefix
-     * using the {@link #getURI getURI} with an argument of "".</p>
-     *
-     * @return An enumeration of all prefixes declared in the
-     *         current context except for the empty (default)
-     *         prefix.
-     * @see #getDeclaredPrefixes
-     * @see #getURI
-     */
-    public Enumeration getPrefixes ()
-    {
-	return currentContext.getPrefixes();
-    }
-
-
-    /**
-     * Return one of the prefixes mapped to a Namespace URI.
-     *
-     * <p>If more than one prefix is currently mapped to the same
-     * URI, this method will make an arbitrary selection; if you
-     * want all of the prefixes, use the {@link #getPrefixes}
-     * method instead.</p>
-     *
-     * <p><strong>Note:</strong> this will never return the empty (default) prefix;
-     * to check for a default prefix, use the {@link #getURI getURI}
-     * method with an argument of "".</p>
-     *
-     * @param uri The Namespace URI.
-     * @param isAttribute true if this prefix is for an attribute
-     *        (and the default Namespace is not allowed).
-     * @return One of the prefixes currently mapped to the URI supplied,
-     *         or null if none is mapped or if the URI is assigned to
-     *         the default Namespace.
-     * @see #getPrefixes(java.lang.String)
-     * @see #getURI
-     */
-    public String getPrefix (String uri)
-    {
-	return currentContext.getPrefix(uri);
-    }
-
-
-    /**
-     * Return an enumeration of all prefixes currently declared for a URI.
-     *
-     * <p>This method returns prefixes mapped to a specific Namespace
-     * URI.  The xml: prefix will be included.  If you want only one
-     * prefix that's mapped to the Namespace URI, and you don't care 
-     * which one you get, use the {@link #getPrefix getPrefix}
-     *  method instead.</p>
-     *
-     * <p><strong>Note:</strong> the empty (default) prefix is <em>never</em> included
-     * in this enumeration; to check for the presence of a default
-     * Namespace, use the {@link #getURI getURI} method with an
-     * argument of "".</p>
-     *
-     * @param uri The Namespace URI.
-     * @return An enumeration of all prefixes declared in the
-     *         current context.
-     * @see #getPrefix
-     * @see #getDeclaredPrefixes
-     * @see #getURI
-     */
-    public Enumeration getPrefixes (String uri)
-    {
-	Vector prefixes = new Vector();
-	Enumeration allPrefixes = getPrefixes();
-	while (allPrefixes.hasMoreElements()) {
-	    String prefix = (String)allPrefixes.nextElement();
-	    if (uri.equals(getURI(prefix))) {
-		prefixes.addElement(prefix);
-	    }
-	}
-	return prefixes.elements();
-    }
-
-
-    /**
-     * Return an enumeration of all prefixes declared in this context.
-     *
-     * <p>The empty (default) prefix will be included in this 
-     * enumeration; note that this behaviour differs from that of
-     * {@link #getPrefix} and {@link #getPrefixes}.</p>
-     *
-     * @return An enumeration of all prefixes declared in this
-     *         context.
-     * @see #getPrefixes
-     * @see #getURI
-     */
-    public Enumeration getDeclaredPrefixes ()
-    {
-	return currentContext.getDeclaredPrefixes();
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Internal state.
-    ////////////////////////////////////////////////////////////////////
-
-    private Context contexts[];
-    private Context currentContext;
-    private int contextPos;
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Internal classes.
-    ////////////////////////////////////////////////////////////////////
-
-    /**
-     * Internal class for a single Namespace context.
-     *
-     * <p>This module caches and reuses Namespace contexts, so the number allocated
-     * will be equal to the element depth of the document, not to the total
-     * number of elements (i.e. 5-10 rather than tens of thousands).</p>
-     */
-    final class Context {
-
-	/**
-	 * Create the root-level Namespace context.
-	 */
-	Context ()
-	{
-	    copyTables();
-	}
-	
-	
-	/**
-	 * (Re)set the parent of this Namespace context.
-	 *
-	 * @param context The parent Namespace context object.
-	 */
-	void setParent (Context parent)
-	{
-	    this.parent = parent;
-	    declarations = null;
-	    prefixTable = parent.prefixTable;
-	    uriTable = parent.uriTable;
-	    elementNameTable = parent.elementNameTable;
-	    attributeNameTable = parent.attributeNameTable;
-	    defaultNS = parent.defaultNS;
-	    tablesDirty = false;
-	}
-	
-	
-	/**
-	 * Declare a Namespace prefix for this context.
-	 *
-	 * @param prefix The prefix to declare.
-	 * @param uri The associated Namespace URI.
-	 * @see org.xml.sax.helpers.NamespaceSupport#declarePrefix
-	 */
-	void declarePrefix (String prefix, String uri)
-	{
-				// Lazy processing...
-	    if (!tablesDirty) {
-		copyTables();
-	    }
-	    if (declarations == null) {
-		declarations = new Vector();
-	    }
-	    
-	    prefix = prefix.intern();
-	    uri = uri.intern();
-	    if ("".equals(prefix)) {
-		if ("".equals(uri)) {
-		    defaultNS = null;
-		} else {
-		    defaultNS = uri;
-		}
-	    } else {
-		prefixTable.put(prefix, uri);
-		uriTable.put(uri, prefix); // may wipe out another prefix
-	    }
-	    declarations.addElement(prefix);
-	}
-
-
-	/**
-	 * Process a raw XML 1.0 name in this context.
-	 *
-	 * @param qName The raw XML 1.0 name.
-	 * @param isAttribute true if this is an attribute name.
-	 * @return An array of three strings containing the
-	 *         URI part (or empty string), the local part,
-	 *         and the raw name, all internalized, or null
-	 *         if there is an undeclared prefix.
-	 * @see org.xml.sax.helpers.NamespaceSupport#processName
-	 */
-	String [] processName (String qName, boolean isAttribute)
-	{
-	    String name[];
-	    Hashtable table;
-	    
-				// Select the appropriate table.
-	    if (isAttribute) {
-		table = elementNameTable;
-	    } else {
-		table = attributeNameTable;
-	    }
-	    
-				// Start by looking in the cache, and
-				// return immediately if the name
-				// is already known in this content
-	    name = (String[])table.get(qName);
-	    if (name != null) {
-		return name;
-	    }
-	    
-				// We haven't seen this name in this
-				// context before.
-	    name = new String[3];
-	    int index = qName.indexOf(':');
-	    
-	    
-				// No prefix.
-	    if (index == -1) {
-		if (isAttribute || defaultNS == null) {
-		    name[0] = "";
-		} else {
-		    name[0] = defaultNS;
-		}
-		name[1] = qName.intern();
-		name[2] = name[1];
-	    }
-	    
-				// Prefix
-	    else {
-		String prefix = qName.substring(0, index);
-		String local = qName.substring(index+1);
-		String uri;
-		if ("".equals(prefix)) {
-		    uri = defaultNS;
-		} else {
-		    uri = (String)prefixTable.get(prefix);
-		}
-		if (uri == null) {
-		    return null;
-		}
-		name[0] = uri;
-		name[1] = local.intern();
-		name[2] = qName.intern();
-	    }
-	    
-				// Save in the cache for future use.
-	    table.put(name[2], name);
-	    tablesDirty = true;
-	    return name;
-	}
-	
-
-	/**
-	 * Look up the URI associated with a prefix in this context.
-	 *
-	 * @param prefix The prefix to look up.
-	 * @return The associated Namespace URI, or null if none is
-	 *         declared.	
-	 * @see org.xml.sax.helpers.NamespaceSupport#getURI
-	 */
-	String getURI (String prefix)
-	{
-	    if ("".equals(prefix)) {
-		return defaultNS;
-	    } else if (prefixTable == null) {
-		return null;
-	    } else {
-		return (String)prefixTable.get(prefix);
-	    }
-	}
-
-
-	/**
-	 * Look up one of the prefixes associated with a URI in this context.
-	 *
-	 * <p>Since many prefixes may be mapped to the same URI,
-	 * the return value may be unreliable.</p>
-	 *
-	 * @param uri The URI to look up.
-	 * @return The associated prefix, or null if none is declared.
-	 * @see org.xml.sax.helpers.NamespaceSupport#getPrefix
-	 */
-	String getPrefix (String uri)
-	{
-	    if (uriTable == null) {
-		return null;
-	    } else {
-		return (String)uriTable.get(uri);
-	    }
-	}
-	
-	
-	/**
-	 * Return an enumeration of prefixes declared in this context.
-	 *
-	 * @return An enumeration of prefixes (possibly empty).
-	 * @see org.xml.sax.helpers.NamespaceSupport#getDeclaredPrefixes
-	 */
-	Enumeration getDeclaredPrefixes ()
-	{
-	    if (declarations == null) {
-		return EMPTY_ENUMERATION;
-	    } else {
-		return declarations.elements();
-	    }
-	}
-	
-	
-	/**
-	 * Return an enumeration of all prefixes currently in force.
-	 *
-	 * <p>The default prefix, if in force, is <em>not</em>
-	 * returned, and will have to be checked for separately.</p>
-	 *
-	 * @return An enumeration of prefixes (never empty).
-	 * @see org.xml.sax.helpers.NamespaceSupport#getPrefixes
-	 */
-	Enumeration getPrefixes ()
-	{
-	    if (prefixTable == null) {
-		return EMPTY_ENUMERATION;
-	    } else {
-		return prefixTable.keys();
-	    }
-	}
-	
-	
-
-	////////////////////////////////////////////////////////////////
-	// Internal methods.
-	////////////////////////////////////////////////////////////////
-
-
-	/**
-	 * Copy on write for the internal tables in this context.
-	 *
-	 * <p>This class is optimized for the normal case where most
-	 * elements do not contain Namespace declarations.</p>
-	 */	
-	private void copyTables ()
-	{
-	    if (prefixTable != null) {
-		prefixTable = (Hashtable)prefixTable.clone();
-	    } else {
-		prefixTable = new Hashtable();
-	    }
-	    if (uriTable != null) {
-		uriTable = (Hashtable)uriTable.clone();
-	    } else {
-		uriTable = new Hashtable();
-	    }
-	    elementNameTable = new Hashtable();
-	    attributeNameTable = new Hashtable();
-	    tablesDirty = true;
-	}
-
-
-
-	////////////////////////////////////////////////////////////////
-	// Protected state.
-	////////////////////////////////////////////////////////////////
-	
-	Hashtable prefixTable;
-	Hashtable uriTable;
-	Hashtable elementNameTable;
-	Hashtable attributeNameTable;
-	String defaultNS = null;
-	
-
-
-	////////////////////////////////////////////////////////////////
-	// Internal state.
-	////////////////////////////////////////////////////////////////
-	
-	private Vector declarations = null;
-	private boolean tablesDirty = false;
-	private Context parent = null;
-    }
-}
-
-// end of NamespaceSupport.java
diff --git a/src/org/xml/sax/helpers/ParserAdapter.java b/src/org/xml/sax/helpers/ParserAdapter.java
deleted file mode 100644
index 432c1c8..0000000
--- a/src/org/xml/sax/helpers/ParserAdapter.java
+++ /dev/null
@@ -1,1008 +0,0 @@
-// ParserAdapter.java - adapt a SAX1 Parser to a SAX2 XMLReader.
-// Written by David Megginson, sax@megginson.com
-// NO WARRANTY!  This class is in the public domain.
-
-// $Id: ParserAdapter.java,v 1.6 2000/05/05 17:50:04 david Exp $
-
-package org.xml.sax.helpers;
-
-import java.io.IOException;
-import java.util.Enumeration;
-
-import org.xml.sax.Parser;	// deprecated
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import org.xml.sax.AttributeList; // deprecated
-import org.xml.sax.EntityResolver;
-import org.xml.sax.DTDHandler;
-import org.xml.sax.DocumentHandler; // deprecated
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-import org.xml.sax.XMLReader;
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXNotRecognizedException;
-import org.xml.sax.SAXNotSupportedException;
-
-
-/**
- * Adapt a SAX1 Parser as a SAX2 XMLReader.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This class wraps a SAX1 {@link org.xml.sax.Parser Parser}
- * and makes it act as a SAX2 {@link org.xml.sax.XMLReader XMLReader},
- * with feature, property, and Namespace support.  Note
- * that it is not possible to report {@link org.xml.sax.ContentHandler#skippedEntity
- * skippedEntity} events, since SAX1 does not make that information available.</p>
- *
- * <p>This adapter does not test for duplicate Namespace-qualified
- * attribute names.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.helpers.XMLReaderAdapter
- * @see org.xml.sax.XMLReader
- * @see org.xml.sax.Parser
- */
-public class ParserAdapter implements XMLReader, DocumentHandler
-{
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Constructors.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Construct a new parser adapter.
-     *
-     * <p>Use the "org.xml.sax.parser" property to locate the
-     * embedded SAX1 driver.</p>
-     *
-     * @exception org.xml.sax.SAXException If the embedded driver
-     *            cannot be instantiated or if the
-     *            org.xml.sax.parser property is not specified.
-     */
-    public ParserAdapter ()
-      throws SAXException
-    {
-	super();
-
-	String driver = System.getProperty("org.xml.sax.parser");
-
-	try {
-	    setup(ParserFactory.makeParser());
-	} catch (ClassNotFoundException e1) {
-	    throw new
-		SAXException("Cannot find SAX1 driver class " +
-			     driver, e1);
-	} catch (IllegalAccessException e2) {
-	    throw new
-		SAXException("SAX1 driver class " +
-			     driver +
-			     " found but cannot be loaded", e2);
-	} catch (InstantiationException e3) {
-	    throw new
-		SAXException("SAX1 driver class " +
-			     driver +
-			     " loaded but cannot be instantiated", e3);
-	} catch (ClassCastException e4) {
-	    throw new
-		SAXException("SAX1 driver class " +
-			     driver +
-			     " does not implement org.xml.sax.Parser");
-	} catch (NullPointerException e5) {
-	    throw new 
-		SAXException("System property org.xml.sax.parser not specified");
-	}
-    }
-
-
-    /**
-     * Construct a new parser adapter.
-     *
-     * <p>Note that the embedded parser cannot be changed once the
-     * adapter is created; to embed a different parser, allocate
-     * a new ParserAdapter.</p>
-     *
-     * @param parser The SAX1 parser to embed.
-     * @exception java.lang.NullPointerException If the parser parameter
-     *            is null.
-     */
-    public ParserAdapter (Parser parser)
-    {
-	super();
-	setup(parser);
-    }
-
-
-    /**
-     * Internal setup method.
-     *
-     * @param parser The embedded parser.
-     * @exception java.lang.NullPointerException If the parser parameter
-     *            is null.
-     */
-    private void setup (Parser parser)
-    {
-	if (parser == null) {
-	    throw new
-		NullPointerException("Parser argument must not be null");
-	}
-	this.parser = parser;
-	atts = new AttributesImpl();
-	nsSupport = new NamespaceSupport();
-	attAdapter = new AttributeListAdapter();
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Implementation of org.xml.sax.XMLReader.
-    ////////////////////////////////////////////////////////////////////
-
-
-    //
-    // Internal constants for the sake of convenience.
-    //
-    private final static String FEATURES = "http://xml.org/sax/features/";
-    private final static String NAMESPACES = FEATURES + "namespaces";
-    private final static String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes";
-    private final static String VALIDATION = FEATURES + "validation";
-    private final static String EXTERNAL_GENERAL =
-	FEATURES + "external-general-entities";
-    private final static String EXTERNAL_PARAMETER =
-	FEATURES + "external-parameter-entities";
-
-
-    /**
-     * Set a feature for the parser.
-     *
-     * <p>The only features supported are namespaces and 
-     * namespace-prefixes.</p>
-     *
-     * @param name The feature name, as a complete URI.
-     * @param state The requested feature state.
-     * @exception org.xml.sax.SAXNotRecognizedException If the feature
-     *            name is not known.
-     * @exception org.xml.sax.SAXNotSupportedException If the feature
-     *            state is not supported.
-     * @see org.xml.sax.XMLReader#setFeature
-     */
-    public void setFeature (String name, boolean state)
-	throws SAXNotRecognizedException, SAXNotSupportedException
-    {
-	if (name.equals(NAMESPACES)) {
-	    checkNotParsing("feature", name);
-	    namespaces = state;
-	    if (!namespaces && !prefixes) {
-		prefixes = true;
-	    }
-	} else if (name.equals(NAMESPACE_PREFIXES)) {
-	    checkNotParsing("feature", name);
-	    prefixes = state;
-	    if (!prefixes && !namespaces) {
-		namespaces = true;
-	    }
-	} else if (name.equals(VALIDATION) ||
-		   name.equals(EXTERNAL_GENERAL) ||
-		   name.equals(EXTERNAL_PARAMETER)) {
-	    throw new SAXNotSupportedException("Feature: " + name);
-	} else {
-	    throw new SAXNotRecognizedException("Feature: " + name);
-	}
-    }
-
-
-    /**
-     * Check a parser feature.
-     *
-     * <p>The only features supported are namespaces and 
-     * namespace-prefixes.</p>
-     *
-     * @param name The feature name, as a complete URI.
-     * @return The current feature state.
-     * @exception org.xml.sax.SAXNotRecognizedException If the feature
-     *            name is not known.
-     * @exception org.xml.sax.SAXNotSupportedException If querying the
-     *            feature state is not supported.
-     * @see org.xml.sax.XMLReader#setFeature
-     */
-    public boolean getFeature (String name)
-	throws SAXNotRecognizedException, SAXNotSupportedException
-    {
-	if (name.equals(NAMESPACES)) {
-	    return namespaces;
-	} else if (name.equals(NAMESPACE_PREFIXES)) {
-	    return prefixes;
-	} else if (name.equals(VALIDATION) ||
-		   name.equals(EXTERNAL_GENERAL) ||
-		   name.equals(EXTERNAL_PARAMETER)) {
-	    throw new SAXNotSupportedException("Feature: " + name);
-	} else {
-	    throw new SAXNotRecognizedException("Feature: " + name);
-	}
-    }
-
-
-    /**
-     * Set a parser property.
-     *
-     * <p>No special properties are currently supported.</p>
-     *
-     * @param name The property name.
-     * @param value The property value.
-     * @exception org.xml.sax.SAXNotRecognizedException If the feature
-     *            name is not known.
-     * @exception org.xml.sax.SAXNotSupportedException If the feature
-     *            state is not supported.
-     * @see org.xml.sax.XMLReader#setProperty
-     */
-    public void setProperty (String name, Object value)
-	throws SAXNotRecognizedException, SAXNotSupportedException
-    {
-	throw new SAXNotRecognizedException("Property: " + name);
-    }
-
-
-    /**
-     * Get a parser property.
-     *
-     * <p>No special properties are currently supported.</p>
-     *
-     * @param name The property name.
-     * @return The property value.
-     * @exception org.xml.sax.SAXNotRecognizedException If the feature
-     *            name is not known.
-     * @exception org.xml.sax.SAXNotSupportedException If the feature
-     *            state is not supported.
-     * @see org.xml.sax.XMLReader#getProperty
-     */
-    public Object getProperty (String name)
-	throws SAXNotRecognizedException, SAXNotSupportedException
-    {
-	throw new SAXNotRecognizedException("Property: " + name);
-    }
-
-
-    /**
-     * Set the entity resolver.
-     *
-     * @param resolver The new entity resolver.
-     * @exception java.lang.NullPointerException If the entity resolver
-     *            parameter is null.
-     * @see org.xml.sax.XMLReader#setEntityResolver
-     */
-    public void setEntityResolver (EntityResolver resolver)
-    {
-	if (resolver == null) {
-	    throw new NullPointerException("Null entity resolver");
-	}
-	entityResolver = resolver;
-    }
-
-
-    /**
-     * Return the current entity resolver.
-     *
-     * @return The current entity resolver, or null if none was supplied.
-     * @see org.xml.sax.XMLReader#getEntityResolver
-     */
-    public EntityResolver getEntityResolver ()
-    {
-	return entityResolver;
-    }
-
-
-    /**
-     * Set the DTD handler.
-     *
-     * @param resolver The new DTD handler.
-     * @exception java.lang.NullPointerException If the DTD handler
-     *            parameter is null.
-     * @see org.xml.sax.XMLReader#setEntityResolver
-     */
-    public void setDTDHandler (DTDHandler handler)
-    {
-	if (handler == null) {
-	    throw new NullPointerException("Null DTD handler");
-	}
-	dtdHandler = handler;
-    }
-
-
-    /**
-     * Return the current DTD handler.
-     *
-     * @return The current DTD handler, or null if none was supplied.
-     * @see org.xml.sax.XMLReader#getEntityResolver
-     */
-    public DTDHandler getDTDHandler ()
-    {
-	return dtdHandler;
-    }
-
-
-    /**
-     * Set the content handler.
-     *
-     * @param resolver The new content handler.
-     * @exception java.lang.NullPointerException If the content handler
-     *            parameter is null.
-     * @see org.xml.sax.XMLReader#setEntityResolver
-     */
-    public void setContentHandler (ContentHandler handler)
-    {
-	if (handler == null) {
-	    throw new NullPointerException("Null content handler");
-	}
-	contentHandler = handler;
-    }
-
-
-    /**
-     * Return the current content handler.
-     *
-     * @return The current content handler, or null if none was supplied.
-     * @see org.xml.sax.XMLReader#getEntityResolver
-     */
-    public ContentHandler getContentHandler ()
-    {
-	return contentHandler;
-    }
-
-
-    /**
-     * Set the error handler.
-     *
-     * @param resolver The new error handler.
-     * @exception java.lang.NullPointerException If the error handler
-     *            parameter is null.
-     * @see org.xml.sax.XMLReader#setEntityResolver
-     */
-    public void setErrorHandler (ErrorHandler handler)
-    {
-	if (handler == null) {
-	    throw new NullPointerException("Null error handler");
-	}
-	errorHandler = handler;
-    }
-
-
-    /**
-     * Return the current error handler.
-     *
-     * @return The current error handler, or null if none was supplied.
-     * @see org.xml.sax.XMLReader#getEntityResolver
-     */
-    public ErrorHandler getErrorHandler ()
-    {
-	return errorHandler;
-    }
-
-
-    /**
-     * Parse an XML document.
-     *
-     * @param systemId The absolute URL of the document.
-     * @exception java.io.IOException If there is a problem reading
-     *            the raw content of the document.
-     * @exception org.xml.sax.SAXException If there is a problem
-     *            processing the document.
-     * @see #parse(org.xml.sax.InputSource)
-     * @see org.xml.sax.Parser#parse(java.lang.String)
-     */
-    public void parse (String systemId)
-	throws IOException, SAXException
-    {
-	parse(new InputSource(systemId));
-    }
-
-
-    /**
-     * Parse an XML document.
-     *
-     * @param input An input source for the document.
-     * @exception java.io.IOException If there is a problem reading
-     *            the raw content of the document.
-     * @exception org.xml.sax.SAXException If there is a problem
-     *            processing the document.
-     * @see #parse(java.lang.String)
-     * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
-     */
-    public void parse (InputSource input)
-	throws IOException, SAXException
-    {
-	if (parsing) {
-	    throw new SAXException("Parser is already in use");
-	}
-	setupParser();
-	parsing = true;
-	try {
-	    parser.parse(input);
-	} finally {
-	    parsing = false;
-	}
-	parsing = false;
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Implementation of org.xml.sax.DocumentHandler.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Adapt a SAX1 document locator event.
-     *
-     * @param locator A document locator.
-     * @see org.xml.sax.ContentHandler#setDocumentLocator
-     */
-    public void setDocumentLocator (Locator locator)
-    {
-	this.locator = locator;
-	if (contentHandler != null) {
-	    contentHandler.setDocumentLocator(locator);
-	}
-    }
-
-
-    /**
-     * Adapt a SAX1 start document event.
-     *
-     * @exception org.xml.sax.SAXException The client may raise a
-     *            processing exception.
-     * @see org.xml.sax.DocumentHandler#startDocument
-     */
-    public void startDocument ()
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.startDocument();
-	}
-    }
-
-
-    /**
-     * Adapt a SAX1 end document event.
-     *
-     * @exception org.xml.sax.SAXException The client may raise a
-     *            processing exception.
-     * @see org.xml.sax.DocumentHandler#endDocument
-     */
-    public void endDocument ()
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.endDocument();
-	}
-    }
-
-
-    /**
-     * Adapt a SAX1 startElement event.
-     *
-     * <p>If necessary, perform Namespace processing.</p>
-     *
-     * @param qName The qualified (prefixed) name.
-     * @param qAtts The XML 1.0 attribute list (with qnames).
-     */
-    public void startElement (String qName, AttributeList qAtts)
-	throws SAXException
-    {
-				// If we're not doing Namespace
-				// processing, dispatch this quickly.
-	if (!namespaces) {
-	    if (contentHandler != null) {
-		attAdapter.setAttributeList(qAtts);
-		contentHandler.startElement("", "", qName.intern(),
-					    attAdapter);
-	    }
-	    return;
-	}
-
-
-				// OK, we're doing Namespace processing.
-	nsSupport.pushContext();
-	boolean seenDecl = false;
-	atts.clear();
-	
-				// Take a first pass and copy all
-				// attributes into the SAX2 attribute
-				// list, noting any Namespace 
-				// declarations.
-	int length = qAtts.getLength();
-	for (int i = 0; i < length; i++) {
-	    String attQName = qAtts.getName(i);
-	    String type = qAtts.getType(i);
-	    String value = qAtts.getValue(i);
-
-				// Found a declaration...
-	    if (attQName.startsWith("xmlns")) {
-		String prefix;
-		int n = attQName.indexOf(':');
-		if (n == -1) {
-		    prefix = "";
-		} else {
-		    prefix = attQName.substring(n+1);
-		}
-		if (!nsSupport.declarePrefix(prefix, value)) {
-		    reportError("Illegal Namespace prefix: " + prefix);
-		}
-		if (contentHandler != null) {
-		    contentHandler.startPrefixMapping(prefix, value);
-		}
-				// We may still have to add this to
-				// the list.
-		if (prefixes) {
-		    atts.addAttribute("", "", attQName.intern(),
-				      type, value);
-		}
-		seenDecl = true;
-
-				// This isn't a declaration.
-	    } else {
-		String attName[] = processName(attQName, true);
-		atts.addAttribute(attName[0], attName[1], attName[2],
-				  type, value);
-	    }
-	}
-	
-				// If there was a Namespace declaration,
-				// we have to make a second pass just
-				// to be safe -- this will happen very
-				// rarely, possibly only once for each
-				// document.
-	if (seenDecl) {
-	    length = atts.getLength();
-	    for (int i = 0; i < length; i++) {
-		String attQName = atts.getQName(i);
-		if (!attQName.startsWith("xmlns")) {
-		    String attName[] = processName(attQName, true);
-		    atts.setURI(i, attName[0]);
-		    atts.setLocalName(i, attName[1]);
-		}
-	    }
-	}
-
-				// OK, finally report the event.
-	if (contentHandler != null) {
-	    String name[] = processName(qName, false);
-	    contentHandler.startElement(name[0], name[1], name[2], atts);
-	}
-    }
-
-
-    /**
-     * Adapt a SAX1 end element event.
-     *
-     * @param qName The qualified (prefixed) name.
-     * @exception org.xml.sax.SAXException The client may raise a
-     *            processing exception.
-     * @see org.xml.sax.DocumentHandler#endElement
-     */
-    public void endElement (String qName)
-	throws SAXException
-    {
-				// If we're not doing Namespace
-				// processing, dispatch this quickly.
-	if (!namespaces) {
-	    if (contentHandler != null) {
-		contentHandler.endElement("", "", qName.intern());
-	    }
-	    return;
-	}
-
-				// Split the name.
-	String names[] = processName(qName, false);
-	if (contentHandler != null) {
-	    contentHandler.endElement(names[0], names[1], names[2]);
-	    Enumeration prefixes = nsSupport.getDeclaredPrefixes();
-	    while (prefixes.hasMoreElements()) {
-		String prefix = (String)prefixes.nextElement();
-		contentHandler.endPrefixMapping(prefix);
-	    }
-	}
-	nsSupport.popContext();
-    }
-
-
-    /**
-     * Adapt a SAX1 characters event.
-     *
-     * @param ch An array of characters.
-     * @param start The starting position in the array.
-     * @param length The number of characters to use.
-     * @exception org.xml.sax.SAXException The client may raise a
-     *            processing exception.
-     * @see org.xml.sax.DocumentHandler#characters
-     */
-    public void characters (char ch[], int start, int length)
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.characters(ch, start, length);
-	}
-    }
-
-
-    /**
-     * Adapt a SAX1 ignorable whitespace event.
-     *
-     * @param ch An array of characters.
-     * @param start The starting position in the array.
-     * @param length The number of characters to use.
-     * @exception org.xml.sax.SAXException The client may raise a
-     *            processing exception.
-     * @see org.xml.sax.DocumentHandler#ignorableWhitespace
-     */
-    public void ignorableWhitespace (char ch[], int start, int length)
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.ignorableWhitespace(ch, start, length);
-	}
-    }
-
-
-    /**
-     * Adapt a SAX1 processing instruction event.
-     *
-     * @param target The processing instruction target.
-     * @param data The remainder of the processing instruction
-     * @exception org.xml.sax.SAXException The client may raise a
-     *            processing exception.
-     * @see org.xml.sax.DocumentHandler#processingInstruction
-     */
-    public void processingInstruction (String target, String data)
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.processingInstruction(target, data);
-	}
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Internal utility methods.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Initialize the parser before each run.
-     */
-    private void setupParser ()
-    {
-	nsSupport.reset();
-
-	if (entityResolver != null) {
-	    parser.setEntityResolver(entityResolver);
-	}
-	if (dtdHandler != null) {
-	    parser.setDTDHandler(dtdHandler);
-	}
-	if (errorHandler != null) {
-	    parser.setErrorHandler(errorHandler);
-	}
-	parser.setDocumentHandler(this);
-	locator = null;
-    }
-
-
-    /**
-     * Process a qualified (prefixed) name.
-     *
-     * <p>If the name has an undeclared prefix, use only the qname
-     * and make an ErrorHandler.error callback in case the app is
-     * interested.</p>
-     *
-     * @param qName The qualified (prefixed) name.
-     * @param isAttribute true if this is an attribute name.
-     * @return The name split into three parts.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception if there is an error callback.
-     */
-    private String [] processName (String qName, boolean isAttribute)
-	throws SAXException
-    {
-	String parts[] = nsSupport.processName(qName, nameParts,
-					       isAttribute);
-	if (parts == null) {
-	    parts = new String[3];
-	    parts[2] = qName.intern();
-	    reportError("Undeclared prefix: " + qName);
-	}
-	return parts;
-    }
-
-
-    /**
-     * Report a non-fatal error.
-     *
-     * @param message The error message.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception.
-     */
-    void reportError (String message)
-	throws SAXException
-    {
-	if (errorHandler == null) {
-	    return;
-	}
-
-	SAXParseException e;
-	if (locator != null) {
-	    e = new SAXParseException(message, locator);
-	} else {
-	    e = new SAXParseException(message, null, null, -1, -1);
-	}
-	errorHandler.error(e);
-    }
-
-
-    /**
-     * Throw an exception if we are parsing.
-     *
-     * <p>Use this method to detect illegal feature or
-     * property changes.</p>
-     *
-     * @param type The type of thing (feature or property).
-     * @param name The feature or property name.
-     * @exception org.xml.sax.SAXNotSupportedException If a
-     *            document is currently being parsed.
-     */
-    private void checkNotParsing (String type, String name)
-	throws SAXNotSupportedException
-    {
-	if (parsing) {
-	    throw new SAXNotSupportedException("Cannot change " +
-					       type + ' ' +
-					       name + " while parsing");
-					       
-	}
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Internal state.
-    ////////////////////////////////////////////////////////////////////
-
-    private NamespaceSupport nsSupport;
-    private AttributeListAdapter attAdapter;
-
-    private boolean parsing = false;
-    private String nameParts[] = new String[3];
-
-    private Parser parser = null;
-
-    private AttributesImpl atts = null;
-
-				// Features
-    private boolean namespaces = true;
-    private boolean prefixes = false;
-
-				// Properties
-
-				// Handlers
-    Locator locator;
-
-    EntityResolver entityResolver = null;
-    DTDHandler dtdHandler = null;
-    ContentHandler contentHandler = null;
-    ErrorHandler errorHandler = null;
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Inner class to wrap an AttributeList when not doing NS proc.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Adapt a SAX1 AttributeList as a SAX2 Attributes object.
-     *
-     * <p>This class is in the Public Domain, and comes with NO
-     * WARRANTY of any kind.</p>
-     *
-     * <p>This wrapper class is used only when Namespace support
-     * is disabled -- it provides pretty much a direct mapping
-     * from SAX1 to SAX2, except that names and types are 
-     * interned whenever requested.</p>
-     */
-    final class AttributeListAdapter implements Attributes
-    {
-
-	/**
-	 * Construct a new adapter.
-	 */
-	AttributeListAdapter ()
-	{
-	}
-
-
-	/**
-	 * Set the embedded AttributeList.
-	 *
-	 * <p>This method must be invoked before any of the others
-	 * can be used.</p>
-	 *
-	 * @param The SAX1 attribute list (with qnames).
-	 */
-	void setAttributeList (AttributeList qAtts)
-	{
-	    this.qAtts = qAtts;
-	}
-
-
-	/**
-	 * Return the length of the attribute list.
-	 *
-	 * @return The number of attributes in the list.
-	 * @see org.xml.sax.Attributes#getLength
-	 */
-	public int getLength ()
-	{
-	    return qAtts.getLength();
-	}
-
-
-	/**
-	 * Return the Namespace URI of the specified attribute.
-	 *
-	 * @param The attribute's index.
-	 * @return Always the empty string.
-	 * @see org.xml.sax.Attributes#getURI
-	 */
-	public String getURI (int i)
-	{
-	    return "";
-	}
-
-
-	/**
-	 * Return the local name of the specified attribute.
-	 *
-	 * @param The attribute's index.
-	 * @return Always the empty string.
-	 * @see org.xml.sax.Attributes#getLocalName
-	 */
-	public String getLocalName (int i)
-	{
-	    return "";
-	}
-
-
-	/**
-	 * Return the qualified (prefixed) name of the specified attribute.
-	 *
-	 * @param The attribute's index.
-	 * @return The attribute's qualified name, internalized.
-	 */
-	public String getQName (int i)
-	{
-	    return qAtts.getName(i).intern();
-	}
-
-
-	/**
-	 * Return the type of the specified attribute.
-	 *
-	 * @param The attribute's index.
-	 * @return The attribute's type as an internalized string.
-	 */
-	public String getType (int i)
-	{
-	    return qAtts.getType(i).intern();
-	}
-
-
-	/**
-	 * Return the value of the specified attribute.
-	 *
-	 * @param The attribute's index.
-	 * @return The attribute's value.
-	 */
-	public String getValue (int i)
-	{
-	    return qAtts.getValue(i);
-	}
-
-
-	/**
-	 * Look up an attribute index by Namespace name.
-	 *
-	 * @param uri The Namespace URI or the empty string.
-	 * @param localName The local name.
-	 * @return The attributes index, or -1 if none was found.
-	 * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String)
-	 */
-	public int getIndex (String uri, String localName)
-	{
-	    return -1;
-	}
-
-
-	/**
-	 * Look up an attribute index by qualified (prefixed) name.
-	 *
-	 * @param qName The qualified name.
-	 * @return The attributes index, or -1 if none was found.
-	 * @see org.xml.sax.Attributes#getIndex(java.lang.String)
-	 */
-	public int getIndex (String qName)
-	{
-	    int max = atts.getLength();
-	    for (int i = 0; i < max; i++) {
-		if (qAtts.getName(i).equals(qName)) {
-		    return i;
-		}
-	    }
-	    return -1;
-	}
-
-
-	/**
-	 * Look up the type of an attribute by Namespace name.
-	 *
-	 * @param uri The Namespace URI
-	 * @param localName The local name.
-	 * @return The attribute's type as an internalized string.
-	 */
-	public String getType (String uri, String localName)
-	{
-	    return null;
-	}
-
-
-	/**
-	 * Look up the type of an attribute by qualified (prefixed) name.
-	 *
-	 * @param qName The qualified name.
-	 * @return The attribute's type as an internalized string.
-	 */
-	public String getType (String qName)
-	{
-	    return qAtts.getType(qName).intern();
-	}
-
-
-	/**
-	 * Look up the value of an attribute by Namespace name.
-	 *
-	 * @param uri The Namespace URI
-	 * @param localName The local name.
-	 * @return The attribute's value.
-	 */
-	public String getValue (String uri, String localName)
-	{
-	    return null;
-	}
-
-
-	/**
-	 * Look up the value of an attribute by qualified (prefixed) name.
-	 *
-	 * @param qName The qualified name.
-	 * @return The attribute's value.
-	 */
-	public String getValue (String qName)
-	{
-	    return qAtts.getValue(qName);
-	}
-
-	private AttributeList qAtts;
-    }
-}
-
-// end of ParserAdapter.java
diff --git a/src/org/xml/sax/helpers/ParserFactory.java b/src/org/xml/sax/helpers/ParserFactory.java
deleted file mode 100644
index 57d4ce1..0000000
--- a/src/org/xml/sax/helpers/ParserFactory.java
+++ /dev/null
@@ -1,129 +0,0 @@
-// SAX parser factory.
-// No warranty; no copyright -- use this as you will.
-// $Id: ParserFactory.java,v 1.4 2000/05/05 17:50:13 david Exp $
-
-package org.xml.sax.helpers;
-
-import java.lang.ClassNotFoundException;
-import java.lang.IllegalAccessException;
-import java.lang.InstantiationException;
-import java.lang.SecurityException;
-import java.lang.ClassCastException;
-
-import org.xml.sax.Parser;
-
-
-/**
- * Java-specific class for dynamically loading SAX parsers.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p><strong>Note:</strong> This class is designed to work with the now-deprecated
- * SAX1 {@link org.xml.sax.Parser Parser} class.  SAX2 applications should use
- * {@link org.xml.sax.helpers.XMLReaderFactory XMLReaderFactory} instead.</p>
- *
- * <p>ParserFactory is not part of the platform-independent definition
- * of SAX; it is an additional convenience class designed
- * specifically for Java XML application writers.  SAX applications
- * can use the static methods in this class to allocate a SAX parser
- * dynamically at run-time based either on the value of the
- * `org.xml.sax.parser' system property or on a string containing the class
- * name.</p>
- *
- * <p>Note that the application still requires an XML parser that
- * implements SAX1.</p>
- *
- * @deprecated This class works with the deprecated
- *             {@link org.xml.sax.Parser Parser}
- *             interface.
- * @since SAX 1.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.Parser
- * @see java.lang.Class
- */
-public class ParserFactory {
-    
-    
-    /**
-     * Private null constructor.
-     */
-    private ParserFactory ()
-    {
-    }
-    
-    
-    /**
-     * Create a new SAX parser using the `org.xml.sax.parser' system property.
-     *
-     * <p>The named class must exist and must implement the
-     * {@link org.xml.sax.Parser Parser} interface.</p>
-     *
-     * @exception java.lang.NullPointerException There is no value
-     *            for the `org.xml.sax.parser' system property.
-     * @exception java.lang.ClassNotFoundException The SAX parser
-     *            class was not found (check your CLASSPATH).
-     * @exception IllegalAccessException The SAX parser class was
-     *            found, but you do not have permission to load
-     *            it.
-     * @exception InstantiationException The SAX parser class was
-     *            found but could not be instantiated.
-     * @exception java.lang.ClassCastException The SAX parser class
-     *            was found and instantiated, but does not implement
-     *            org.xml.sax.Parser.
-     * @see #makeParser(java.lang.String)
-     * @see org.xml.sax.Parser
-     */
-    public static Parser makeParser ()
-	throws ClassNotFoundException,
-	IllegalAccessException, 
-	InstantiationException,
-	NullPointerException,
-	ClassCastException
-    {
-	String className = System.getProperty("org.xml.sax.parser");
-	if (className == null) {
-	    throw new NullPointerException("No value for sax.parser property");
-	} else {
-	    return makeParser(className);
-	}
-    }
-    
-    
-    /**
-     * Create a new SAX parser object using the class name provided.
-     *
-     * <p>The named class must exist and must implement the
-     * {@link org.xml.sax.Parser Parser} interface.</p>
-     *
-     * @param className A string containing the name of the
-     *                  SAX parser class.
-     * @exception java.lang.ClassNotFoundException The SAX parser
-     *            class was not found (check your CLASSPATH).
-     * @exception IllegalAccessException The SAX parser class was
-     *            found, but you do not have permission to load
-     *            it.
-     * @exception InstantiationException The SAX parser class was
-     *            found but could not be instantiated.
-     * @exception java.lang.ClassCastException The SAX parser class
-     *            was found and instantiated, but does not implement
-     *            org.xml.sax.Parser.
-     * @see #makeParser()
-     * @see org.xml.sax.Parser
-     */
-    public static Parser makeParser (String className)
-	throws ClassNotFoundException,
-	IllegalAccessException, 
-	InstantiationException,
-	ClassCastException
-    {
-	return (Parser)(Class.forName(className).newInstance());
-    }
-    
-}
-
-// end of ParserFactory.java
diff --git a/src/org/xml/sax/helpers/XMLFilterImpl.java b/src/org/xml/sax/helpers/XMLFilterImpl.java
deleted file mode 100644
index 93c2372..0000000
--- a/src/org/xml/sax/helpers/XMLFilterImpl.java
+++ /dev/null
@@ -1,769 +0,0 @@
-// XMLFilterImpl.java - base SAX2 filter implementation.
-// Written by David Megginson, sax@megginson.com
-// NO WARRANTY!  This class is in the Public Domain.
-
-// $Id: XMLFilterImpl.java,v 1.4 2000/05/05 17:50:37 david Exp $
-
-package org.xml.sax.helpers;
-
-import java.io.IOException;
-
-import org.xml.sax.XMLReader;
-import org.xml.sax.XMLFilter;
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import org.xml.sax.Attributes;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.DTDHandler;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.SAXNotSupportedException;
-import org.xml.sax.SAXNotRecognizedException;
-
-
-/**
- * Base class for deriving an XML filter.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This class is designed to sit between an {@link org.xml.sax.XMLReader
- * XMLReader} and the client application's event handlers.  By default, it
- * does nothing but pass requests up to the reader and events
- * on to the handlers unmodified, but subclasses can override
- * specific methods to modify the event stream or the configuration
- * requests as they pass through.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.XMLFilter
- * @see org.xml.sax.XMLReader
- * @see org.xml.sax.EntityResolver
- * @see org.xml.sax.DTDHandler
- * @see org.xml.sax.ContentHandler
- * @see org.xml.sax.ErrorHandler
- */
-public class XMLFilterImpl
-    implements XMLFilter, EntityResolver, DTDHandler, ContentHandler, ErrorHandler
-{
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Constructors.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Construct an empty XML filter, with no parent.
-     *
-     * <p>This filter will have no parent: you must assign a parent
-     * before you start a parse or do any configuration with
-     * setFeature or setProperty.</p>
-     *
-     * @see org.xml.sax.XMLReader#setFeature
-     * @see org.xml.sax.XMLReader#setProperty
-     */
-    public XMLFilterImpl ()
-    {
-	super();
-    }
-
-
-    /**
-     * Construct an XML filter with the specified parent.
-     *
-     * @see #setParent
-     * @see #getParent
-     */
-    public XMLFilterImpl (XMLReader parent)
-    {
-        super();
-	setParent(parent);
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Implementation of org.xml.sax.XMLFilter.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Set the parent reader.
-     *
-     * <p>This is the {@link org.xml.sax.XMLReader XMLReader} from which 
-     * this filter will obtain its events and to which it will pass its 
-     * configuration requests.  The parent may itself be another filter.</p>
-     *
-     * <p>If there is no parent reader set, any attempt to parse
-     * or to set or get a feature or property will fail.</p>
-     *
-     * @param parent The parent XML reader.
-     * @exception java.lang.NullPointerException If the parent is null.
-     * @see #getParent
-     */
-    public void setParent (XMLReader parent)
-    {
-	if (parent == null) {
-	    throw new NullPointerException("Null parent");
-	}
-	this.parent = parent;
-    }
-
-
-    /**
-     * Get the parent reader.
-     *
-     * @return The parent XML reader, or null if none is set.
-     * @see #setParent
-     */
-    public XMLReader getParent ()
-    {
-	return parent;
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Implementation of org.xml.sax.XMLReader.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Set the state of a feature.
-     *
-     * <p>This will always fail if the parent is null.</p>
-     *
-     * @param name The feature name.
-     * @param state The requested feature state.
-     * @exception org.xml.sax.SAXNotRecognizedException When the
-     *            XMLReader does not recognize the feature name.
-     * @exception org.xml.sax.SAXNotSupportedException When the
-     *            XMLReader recognizes the feature name but 
-     *            cannot set the requested value.
-     * @see org.xml.sax.XMLReader#setFeature
-     */
-    public void setFeature (String name, boolean state)
-	throws SAXNotRecognizedException, SAXNotSupportedException
-    {
-	if (parent != null) {
-	    parent.setFeature(name, state);
-	} else {
-	    throw new SAXNotRecognizedException("Feature: " + name);
-	}
-    }
-
-
-    /**
-     * Look up the state of a feature.
-     *
-     * <p>This will always fail if the parent is null.</p>
-     *
-     * @param name The feature name.
-     * @return The current state of the feature.
-     * @exception org.xml.sax.SAXNotRecognizedException When the
-     *            XMLReader does not recognize the feature name.
-     * @exception org.xml.sax.SAXNotSupportedException When the
-     *            XMLReader recognizes the feature name but 
-     *            cannot determine its state at this time.
-     * @see org.xml.sax.XMLReader#getFeature
-     */
-    public boolean getFeature (String name)
-	throws SAXNotRecognizedException, SAXNotSupportedException
-    {
-	if (parent != null) {
-	    return parent.getFeature(name);
-	} else {
-	    throw new SAXNotRecognizedException("Feature: " + name);
-	}
-    }
-
-
-    /**
-     * Set the value of a property.
-     *
-     * <p>This will always fail if the parent is null.</p>
-     *
-     * @param name The property name.
-     * @param state The requested property value.
-     * @exception org.xml.sax.SAXNotRecognizedException When the
-     *            XMLReader does not recognize the property name.
-     * @exception org.xml.sax.SAXNotSupportedException When the
-     *            XMLReader recognizes the property name but 
-     *            cannot set the requested value.
-     * @see org.xml.sax.XMLReader#setProperty
-     */
-    public void setProperty (String name, Object value)
-	throws SAXNotRecognizedException, SAXNotSupportedException
-    {
-	if (parent != null) {
-	    parent.setProperty(name, value);
-	} else {
-	    throw new SAXNotRecognizedException("Property: " + name);
-	}
-    }
-
-
-    /**
-     * Look up the value of a property.
-     *
-     * @param name The property name.
-     * @return The current value of the property.
-     * @exception org.xml.sax.SAXNotRecognizedException When the
-     *            XMLReader does not recognize the feature name.
-     * @exception org.xml.sax.SAXNotSupportedException When the
-     *            XMLReader recognizes the property name but 
-     *            cannot determine its value at this time.
-     * @see org.xml.sax.XMLReader#setFeature
-     */
-    public Object getProperty (String name)
-	throws SAXNotRecognizedException, SAXNotSupportedException
-    {
-	if (parent != null) {
-	    return parent.getProperty(name);
-	} else {
-	    throw new SAXNotRecognizedException("Property: " + name);
-	}
-    }
-
-
-    /**
-     * Set the entity resolver.
-     *
-     * @param resolver The new entity resolver.
-     * @exception java.lang.NullPointerException If the resolver
-     *            is null.
-     * @see org.xml.sax.XMLReader#setEntityResolver
-     */
-    public void setEntityResolver (EntityResolver resolver)
-    {
-	if (resolver == null) {
-	    throw new NullPointerException("Null entity resolver");
-	} else {
-	    entityResolver = resolver;
-	}
-    }
-
-
-    /**
-     * Get the current entity resolver.
-     *
-     * @return The current entity resolver, or null if none was set.
-     * @see org.xml.sax.XMLReader#getEntityResolver
-     */
-    public EntityResolver getEntityResolver ()
-    {
-	return entityResolver;
-    }
-
-
-    /**
-     * Set the DTD event handler.
-     *
-     * @param resolver The new DTD handler.
-     * @exception java.lang.NullPointerException If the handler
-     *            is null.
-     * @see org.xml.sax.XMLReader#setDTDHandler
-     */
-    public void setDTDHandler (DTDHandler handler)
-    {
-	if (handler == null) {
-	    throw new NullPointerException("Null DTD handler");
-	} else {
-	    dtdHandler = handler;
-	}
-    }
-
-
-    /**
-     * Get the current DTD event handler.
-     *
-     * @return The current DTD handler, or null if none was set.
-     * @see org.xml.sax.XMLReader#getDTDHandler
-     */
-    public DTDHandler getDTDHandler ()
-    {
-	return dtdHandler;
-    }
-
-
-    /**
-     * Set the content event handler.
-     *
-     * @param resolver The new content handler.
-     * @exception java.lang.NullPointerException If the handler
-     *            is null.
-     * @see org.xml.sax.XMLReader#setContentHandler
-     */
-    public void setContentHandler (ContentHandler handler)
-    {
-	if (handler == null) {
-	    throw new NullPointerException("Null content handler");
-	} else {
-	    contentHandler = handler;
-	}
-    }
-
-
-    /**
-     * Get the content event handler.
-     *
-     * @return The current content handler, or null if none was set.
-     * @see org.xml.sax.XMLReader#getContentHandler
-     */
-    public ContentHandler getContentHandler ()
-    {
-	return contentHandler;
-    }
-
-
-    /**
-     * Set the error event handler.
-     *
-     * @param handle The new error handler.
-     * @exception java.lang.NullPointerException If the handler
-     *            is null.
-     * @see org.xml.sax.XMLReader#setErrorHandler
-     */
-    public void setErrorHandler (ErrorHandler handler)
-    {
-	if (handler == null) {
-	    throw new NullPointerException("Null error handler");
-	} else {
-	    errorHandler = handler;
-	}
-    }
-
-
-    /**
-     * Get the current error event handler.
-     *
-     * @return The current error handler, or null if none was set.
-     * @see org.xml.sax.XMLReader#getErrorHandler
-     */
-    public ErrorHandler getErrorHandler ()
-    {
-	return errorHandler;
-    }
-
-
-    /**
-     * Parse a document.
-     *
-     * @param input The input source for the document entity.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @exception java.io.IOException An IO exception from the parser,
-     *            possibly from a byte stream or character stream
-     *            supplied by the application.
-     * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
-     */
-    public void parse (InputSource input)
-	throws SAXException, IOException
-    {
-	setupParse();
-	parent.parse(input);
-    }
-
-
-    /**
-     * Parse a document.
-     *
-     * @param systemId The system identifier as a fully-qualified URI.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @exception java.io.IOException An IO exception from the parser,
-     *            possibly from a byte stream or character stream
-     *            supplied by the application.
-     * @see org.xml.sax.XMLReader#parse(java.lang.String)
-     */
-    public void parse (String systemId)
-	throws SAXException, IOException
-    {
-	parse(new InputSource(systemId));
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Implementation of org.xml.sax.EntityResolver.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Filter an external entity resolution.
-     *
-     * @param publicId The entity's public identifier, or null.
-     * @param systemId The entity's system identifier.
-     * @return A new InputSource or null for the default.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @exception java.io.IOException The client may throw an
-     *            I/O-related exception while obtaining the
-     *            new InputSource.
-     * @see org.xml.sax.EntityResolver#resolveEntity
-     */
-    public InputSource resolveEntity (String publicId, String systemId)
-	throws SAXException, IOException
-    {
-	if (entityResolver != null) {
-	    return entityResolver.resolveEntity(publicId, systemId);
-	} else {
-	    return null;
-	}
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Implementation of org.xml.sax.DTDHandler.
-    ////////////////////////////////////////////////////////////////////
-
-    
-    /**
-     * Filter a notation declaration event.
-     *
-     * @param name The notation name.
-     * @param publicId The notation's public identifier, or null.
-     * @param systemId The notation's system identifier, or null.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.DTDHandler#notationDecl
-     */
-    public void notationDecl (String name, String publicId, String systemId)
-	throws SAXException
-    {
-	if (dtdHandler != null) {
-	    dtdHandler.notationDecl(name, publicId, systemId);
-	}
-    }
-
-    
-    /**
-     * Filter an unparsed entity declaration event.
-     *
-     * @param name The entity name.
-     * @param publicId The entity's public identifier, or null.
-     * @param systemId The entity's system identifier, or null.
-     * @param notationName The name of the associated notation.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.DTDHandler#unparsedEntityDecl
-     */
-    public void unparsedEntityDecl (String name, String publicId,
-				    String systemId, String notationName)
-	throws SAXException
-    {
-	if (dtdHandler != null) {
-	    dtdHandler.unparsedEntityDecl(name, publicId, systemId,
-					  notationName);
-	}
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Implementation of org.xml.sax.ContentHandler.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Filter a new document locator event.
-     *
-     * @param locator The document locator.
-     * @see org.xml.sax.ContentHandler#setDocumentLocator
-     */
-    public void setDocumentLocator (Locator locator)
-    {
-	this.locator = locator;
-	if (contentHandler != null) {
-	    contentHandler.setDocumentLocator(locator);
-	}
-    }
-
-
-    /**
-     * Filter a start document event.
-     *
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.ContentHandler#startDocument
-     */
-    public void startDocument ()
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.startDocument();
-	}
-    }
-
-
-    /**
-     * Filter an end document event.
-     *
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.ContentHandler#endDocument
-     */
-    public void endDocument ()
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.endDocument();
-	}
-    }
-
-
-    /**
-     * Filter a start Namespace prefix mapping event.
-     *
-     * @param prefix The Namespace prefix.
-     * @param uri The Namespace URI.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.ContentHandler#startPrefixMapping
-     */
-    public void startPrefixMapping (String prefix, String uri)
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.startPrefixMapping(prefix, uri);
-	}
-    }
-
-
-    /**
-     * Filter an end Namespace prefix mapping event.
-     *
-     * @param prefix The Namespace prefix.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.ContentHandler#endPrefixMapping
-     */
-    public void endPrefixMapping (String prefix)
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.endPrefixMapping(prefix);
-	}
-    }
-
-
-    /**
-     * Filter a start element event.
-     *
-     * @param uri The element's Namespace URI, or the empty string.
-     * @param localName The element's local name, or the empty string.
-     * @param qName The element's qualified (prefixed) name, or the empty
-     *        string.
-     * @param atts The element's attributes.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.ContentHandler#startElement
-     */
-    public void startElement (String uri, String localName, String qName,
-			      Attributes atts)
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.startElement(uri, localName, qName, atts);
-	}
-    }
-
-
-    /**
-     * Filter an end element event.
-     *
-     * @param uri The element's Namespace URI, or the empty string.
-     * @param localName The element's local name, or the empty string.
-     * @param qName The element's qualified (prefixed) name, or the empty
-     *        string.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.ContentHandler#endElement
-     */
-    public void endElement (String uri, String localName, String qName)
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.endElement(uri, localName, qName);
-	}
-    }
-
-
-    /**
-     * Filter a character data event.
-     *
-     * @param ch An array of characters.
-     * @param start The starting position in the array.
-     * @param length The number of characters to use from the array.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.ContentHandler#characters
-     */
-    public void characters (char ch[], int start, int length)
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.characters(ch, start, length);
-	}
-    }
-
-
-    /**
-     * Filter an ignorable whitespace event.
-     *
-     * @param ch An array of characters.
-     * @param start The starting position in the array.
-     * @param length The number of characters to use from the array.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.ContentHandler#ignorableWhitespace
-     */
-    public void ignorableWhitespace (char ch[], int start, int length)
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.ignorableWhitespace(ch, start, length);
-	}
-    }
-
-
-    /**
-     * Filter a processing instruction event.
-     *
-     * @param target The processing instruction target.
-     * @param data The text following the target.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.ContentHandler#processingInstruction
-     */
-    public void processingInstruction (String target, String data)
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.processingInstruction(target, data);
-	}
-    }
-
-
-    /**
-     * Filter a skipped entity event.
-     *
-     * @param name The name of the skipped entity.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.ContentHandler#skippedEntity
-     */
-    public void skippedEntity (String name)
-	throws SAXException
-    {
-	if (contentHandler != null) {
-	    contentHandler.skippedEntity(name);
-	}
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Implementation of org.xml.sax.ErrorHandler.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Filter a warning event.
-     *
-     * @param e The nwarning as an exception.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.ErrorHandler#warning
-     */
-    public void warning (SAXParseException e)
-	throws SAXException
-    {
-	if (errorHandler != null) {
-	    errorHandler.warning(e);
-	}
-    }
-
-
-    /**
-     * Filter an error event.
-     *
-     * @param e The error as an exception.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.ErrorHandler#error
-     */
-    public void error (SAXParseException e)
-	throws SAXException
-    {
-	if (errorHandler != null) {
-	    errorHandler.error(e);
-	}
-    }
-
-
-    /**
-     * Filter a fatal error event.
-     *
-     * @param e The error as an exception.
-     * @exception org.xml.sax.SAXException The client may throw
-     *            an exception during processing.
-     * @see org.xml.sax.ErrorHandler#fatalError
-     */
-    public void fatalError (SAXParseException e)
-	throws SAXException
-    {
-	if (errorHandler != null) {
-	    errorHandler.fatalError(e);
-	}
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Internal methods.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Set up before a parse.
-     *
-     * <p>Before every parse, check whether the parent is
-     * non-null, and re-register the filter for all of the 
-     * events.</p>
-     */
-    private void setupParse ()
-    {
-	if (parent == null) {
-	    throw new NullPointerException("No parent for filter");
-	}
-	parent.setEntityResolver(this);
-	parent.setDTDHandler(this);
-	parent.setContentHandler(this);
-	parent.setErrorHandler(this);
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Internal state.
-    ////////////////////////////////////////////////////////////////////
-
-    private XMLReader parent = null;
-    private Locator locator = null;
-    private EntityResolver entityResolver = null;
-    private DTDHandler dtdHandler = null;
-    private ContentHandler contentHandler = null;
-    private ErrorHandler errorHandler = null;
-
-}
-
-// end of XMLFilterImpl.java
diff --git a/src/org/xml/sax/helpers/XMLReaderAdapter.java b/src/org/xml/sax/helpers/XMLReaderAdapter.java
deleted file mode 100644
index d9fd150..0000000
--- a/src/org/xml/sax/helpers/XMLReaderAdapter.java
+++ /dev/null
@@ -1,526 +0,0 @@
-// XMLReaderAdapter.java - adapt an SAX2 XMLReader to a SAX1 Parser
-// Written by David Megginson, sax@megginson.com
-// NO WARRANTY!  This class is in the public domain.
-
-// $Id: XMLReaderAdapter.java,v 1.5 2000/05/05 17:50:46 david Exp $
-
-package org.xml.sax.helpers;
-
-import java.io.IOException;
-import java.util.Locale;
-
-import org.xml.sax.Parser;	// deprecated
-import org.xml.sax.Locator;
-import org.xml.sax.InputSource;
-import org.xml.sax.AttributeList; // deprecated
-import org.xml.sax.EntityResolver;
-import org.xml.sax.DTDHandler;
-import org.xml.sax.DocumentHandler; // deprecated
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-
-import org.xml.sax.XMLReader;
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXNotSupportedException;
-
-
-/**
- * Adapt a SAX2 XMLReader as a SAX1 Parser.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This class wraps a SAX2 {@link org.xml.sax.XMLReader XMLReader}
- * and makes it act as a SAX1 {@link org.xml.sax.Parser Parser}.  The XMLReader 
- * must support a true value for the 
- * http://xml.org/sax/features/namespace-prefixes property or parsing will fail
- * with a {@link org.xml.sax.SAXException SAXException}; if the XMLReader 
- * supports a false value for the http://xml.org/sax/features/namespaces 
- * property, that will also be used to improve efficiency.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.Parser
- * @see org.xml.sax.XMLReader
- */
-public class XMLReaderAdapter implements Parser, ContentHandler
-{
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Constructor.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Create a new adapter.
-     *
-     * <p>Use the "org.xml.sax.driver" property to locate the SAX2
-     * driver to embed.</p>
-     *
-     * @exception org.xml.sax.SAXException If the embedded driver
-     *            cannot be instantiated or if the
-     *            org.xml.sax.driver property is not specified.
-     */
-    public XMLReaderAdapter ()
-      throws SAXException
-    {
-	setup(XMLReaderFactory.createXMLReader());
-    }
-
-
-    /**
-     * Create a new adapter.
-     *
-     * <p>Create a new adapter, wrapped around a SAX2 XMLReader.
-     * The adapter will make the XMLReader act like a SAX1
-     * Parser.</p>
-     *
-     * @param xmlReader The SAX2 XMLReader to wrap.
-     * @exception java.lang.NullPointerException If the argument is null.
-     */
-    public XMLReaderAdapter (XMLReader xmlReader)
-    {
-	setup(xmlReader);
-    }
-
-
-
-    /**
-     * Internal setup.
-     *
-     * @param xmlReader The embedded XMLReader.
-     */
-    private void setup (XMLReader xmlReader)
-    {
-	if (xmlReader == null) {
-	    throw new NullPointerException("XMLReader must not be null");
-	}
-	this.xmlReader = xmlReader;
-	qAtts = new AttributesAdapter();
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Implementation of org.xml.sax.Parser.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Set the locale for error reporting.
-     *
-     * <p>This is not supported in SAX2, and will always throw
-     * an exception.</p>
-     *
-     * @param The locale for error reporting.
-     * @see org.xml.sax.Parser#setLocale
-     */
-    public void setLocale (Locale locale)
-	throws SAXException
-    {
-	throw new SAXNotSupportedException("setLocale not supported");
-    }
-
-
-    /**
-     * Register the entity resolver.
-     *
-     * @param resolver The new resolver.
-     * @see org.xml.sax.Parser#setEntityResolver
-     */
-    public void setEntityResolver (EntityResolver resolver)
-    {
-	xmlReader.setEntityResolver(resolver);
-    }
-
-
-    /**
-     * Register the DTD event handler.
-     *
-     * @param handler The new DTD event handler.
-     * @see org.xml.sax.Parser#setDTDHandler
-     */
-    public void setDTDHandler (DTDHandler handler)
-    {
-	xmlReader.setDTDHandler(handler);
-    }
-
-
-    /**
-     * Register the SAX1 document event handler.
-     *
-     * <p>Note that the SAX1 document handler has no Namespace
-     * support.</p>
-     *
-     * @param handler The new SAX1 document event handler.
-     * @see org.xml.sax.Parser#setDocumentHandler
-     */
-    public void setDocumentHandler (DocumentHandler handler)
-    {
-	documentHandler = handler;
-    }
-
-
-    /**
-     * Register the error event handler.
-     *
-     * @param handler The new error event handler.
-     * @see org.xml.sax.Parser#setErrorHandler
-     */
-    public void setErrorHandler (ErrorHandler handler)
-    {
-	xmlReader.setErrorHandler(handler);
-    }
-
-
-    /**
-     * Parse the document.
-     *
-     * <p>This method will throw an exception if the embedded
-     * XMLReader does not support the 
-     * http://xml.org/sax/features/namespace-prefixes property.</p>
-     *
-     * @param systemId The absolute URL of the document.
-     * @exception java.io.IOException If there is a problem reading
-     *            the raw content of the document.
-     * @exception org.xml.sax.SAXException If there is a problem
-     *            processing the document.
-     * @see #parse(org.xml.sax.InputSource)
-     * @see org.xml.sax.Parser#parse(java.lang.String)
-     */
-    public void parse (String systemId)
-	throws IOException, SAXException
-    {
-	parse(new InputSource(systemId));
-    }
-
-
-    /**
-     * Parse the document.
-     *
-     * <p>This method will throw an exception if the embedded
-     * XMLReader does not support the 
-     * http://xml.org/sax/features/namespace-prefixes property.</p>
-     *
-     * @param input An input source for the document.
-     * @exception java.io.IOException If there is a problem reading
-     *            the raw content of the document.
-     * @exception org.xml.sax.SAXException If there is a problem
-     *            processing the document.
-     * @see #parse(java.lang.String)
-     * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
-     */
-    public void parse (InputSource input)
-	throws IOException, SAXException
-    {
-	setupXMLReader();
-	xmlReader.parse(input);
-    }
-
-
-    /**
-     * Set up the XML reader.
-     */
-    private void setupXMLReader ()
-	throws SAXException
-    {
-	xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
-	try {
-	    xmlReader.setFeature("http://xml.org/sax/features/namespaces",
-	                         false);
-	} catch (SAXException e) {
-	    // NO OP: it's just extra information, and we can ignore it
-	}
-	xmlReader.setContentHandler(this);
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Implementation of org.xml.sax.ContentHandler.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Set a document locator.
-     *
-     * @param locator The document locator.
-     * @see org.xml.sax.ContentHandler#setDocumentLocator
-     */
-    public void setDocumentLocator (Locator locator)
-    {
-	documentHandler.setDocumentLocator(locator);
-    }
-
-
-    /**
-     * Start document event.
-     *
-     * @exception org.xml.sax.SAXException The client may raise a
-     *            processing exception.
-     * @see org.xml.sax.ContentHandler#startDocument
-     */
-    public void startDocument ()
-	throws SAXException
-    {
-	documentHandler.startDocument();
-    }
-
-
-    /**
-     * End document event.
-     *
-     * @exception org.xml.sax.SAXException The client may raise a
-     *            processing exception.
-     * @see org.xml.sax.ContentHandler#endDocument
-     */
-    public void endDocument ()
-	throws SAXException
-    {
-	documentHandler.endDocument();
-    }
-
-
-    /**
-     * Adapt a SAX2 start prefix mapping event.
-     *
-     * @param prefix The prefix being mapped.
-     * @param uri The Namespace URI being mapped to.
-     * @see org.xml.sax.ContentHandler#startPrefixMapping
-     */
-    public void startPrefixMapping (String prefix, String uri)
-    {
-    }
-
-
-    /**
-     * Adapt a SAX2 end prefix mapping event.
-     *
-     * @param prefix The prefix being mapped.
-     * @see org.xml.sax.ContentHandler#endPrefixMapping
-     */
-    public void endPrefixMapping (String prefix)
-    {
-    }
-
-
-    /**
-     * Adapt a SAX2 start element event.
-     *
-     * @param uri The Namespace URI.
-     * @param localName The Namespace local name.
-     * @param qName The qualified (prefixed) name.
-     * @param atts The SAX2 attributes.
-     * @exception org.xml.sax.SAXException The client may raise a
-     *            processing exception.
-     * @see org.xml.sax.ContentHandler#endDocument
-     */
-    public void startElement (String uri, String localName,
-			      String qName, Attributes atts)
-	throws SAXException
-    {
-	qAtts.setAttributes(atts);
-	documentHandler.startElement(qName, qAtts);
-    }
-
-
-    /**
-     * Adapt a SAX2 end element event.
-     *
-     * @param uri The Namespace URI.
-     * @param localName The Namespace local name.
-     * @param qName The qualified (prefixed) name.
-     * @exception org.xml.sax.SAXException The client may raise a
-     *            processing exception.
-     * @see org.xml.sax.ContentHandler#endElement
-     */
-    public void endElement (String uri, String localName,
-			    String qName)
-	throws SAXException
-    {
-	documentHandler.endElement(qName);
-    }
-
-
-    /**
-     * Adapt a SAX2 characters event.
-     *
-     * @param ch An array of characters.
-     * @param start The starting position in the array.
-     * @param length The number of characters to use.
-     * @exception org.xml.sax.SAXException The client may raise a
-     *            processing exception.
-     * @see org.xml.sax.ContentHandler#characters
-     */
-    public void characters (char ch[], int start, int length)
-	throws SAXException
-    {
-	documentHandler.characters(ch, start, length);
-    }
-
-
-    /**
-     * Adapt a SAX2 ignorable whitespace event.
-     *
-     * @param ch An array of characters.
-     * @param start The starting position in the array.
-     * @param length The number of characters to use.
-     * @exception org.xml.sax.SAXException The client may raise a
-     *            processing exception.
-     * @see org.xml.sax.ContentHandler#ignorableWhitespace
-     */
-    public void ignorableWhitespace (char ch[], int start, int length)
-	throws SAXException
-    {
-	documentHandler.ignorableWhitespace(ch, start, length);
-    }
-
-
-    /**
-     * Adapt a SAX2 processing instruction event.
-     *
-     * @param target The processing instruction target.
-     * @param data The remainder of the processing instruction
-     * @exception org.xml.sax.SAXException The client may raise a
-     *            processing exception.
-     * @see org.xml.sax.ContentHandler#processingInstruction
-     */
-    public void processingInstruction (String target, String data)
-	throws SAXException
-    {
-	documentHandler.processingInstruction(target, data);
-    }
-
-
-    /**
-     * Adapt a SAX2 skipped entity event.
-     *
-     * @param name The name of the skipped entity.
-     * @see org.xml.sax.ContentHandler#skippedEntity
-     */
-    public void skippedEntity (String name)
-	throws SAXException
-    {
-    }
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Internal state.
-    ////////////////////////////////////////////////////////////////////
-
-    XMLReader xmlReader;
-    DocumentHandler documentHandler;
-    AttributesAdapter qAtts;
-
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Internal class.
-    ////////////////////////////////////////////////////////////////////
-
-
-    /**
-     * Internal class to wrap a SAX2 Attributes object for SAX1.
-     */
-    final class AttributesAdapter implements AttributeList
-    {
-	AttributesAdapter ()
-	{
-	}
-
-
-	/**
-	 * Set the embedded Attributes object.
-	 *
-	 * @param The embedded SAX2 Attributes.
-	 */ 
-	void setAttributes (Attributes attributes)
-	{
-	    this.attributes = attributes;
-	}
-
-
-	/**
-	 * Return the number of attributes.
-	 *
-	 * @return The length of the attribute list.
-	 * @see org.xml.sax.AttributeList#getLength
-	 */
-	public int getLength ()
-	{
-	    return attributes.getLength();
-	}
-
-
-	/**
-	 * Return the qualified (prefixed) name of an attribute by position.
-	 *
-	 * @return The qualified name.
-	 * @see org.xml.sax.AttributeList#getName
-	 */
-	public String getName (int i)
-	{
-	    return attributes.getQName(i);
-	}
-
-
-	/**
-	 * Return the type of an attribute by position.
-	 *
-	 * @return The type.
-	 * @see org.xml.sax.AttributeList#getType(int)
-	 */
-	public String getType (int i)
-	{
-	    return attributes.getType(i);
-	}
-
-
-	/**
-	 * Return the value of an attribute by position.
-	 *
-	 * @return The value.
-	 * @see org.xml.sax.AttributeList#getValue(int)
-	 */
-	public String getValue (int i)
-	{
-	    return attributes.getValue(i);
-	}
-
-
-	/**
-	 * Return the type of an attribute by qualified (prefixed) name.
-	 *
-	 * @return The type.
-	 * @see org.xml.sax.AttributeList#getType(java.lang.String)
-	 */
-	public String getType (String qName)
-	{
-	    return attributes.getType(qName);
-	}
-
-
-	/**
-	 * Return the value of an attribute by qualified (prefixed) name.
-	 *
-	 * @return The value.
-	 * @see org.xml.sax.AttributeList#getValue(java.lang.String)
-	 */
-	public String getValue (String qName)
-	{
-	    return attributes.getValue(qName);
-	}
-
-	private Attributes attributes;
-    }
-
-}
-
-// end of XMLReaderAdapter.java
diff --git a/src/org/xml/sax/helpers/XMLReaderFactory.java b/src/org/xml/sax/helpers/XMLReaderFactory.java
deleted file mode 100644
index d7f12ff..0000000
--- a/src/org/xml/sax/helpers/XMLReaderFactory.java
+++ /dev/null
@@ -1,136 +0,0 @@
-// XMLReaderFactory.java - factory for creating a new reader.
-// Written by David Megginson, sax@megginson.com
-// NO WARRANTY!  This class is in the Public Domain.
-
-// $Id: XMLReaderFactory.java,v 1.3 2000/05/05 17:50:53 david Exp $
-
-package org.xml.sax.helpers;
-import org.xml.sax.Parser;
-import org.xml.sax.XMLReader;
-import org.xml.sax.SAXException;
-
-
-/**
- * Factory for creating an XML reader.
- *
- * <blockquote>
- * <em>This module, both source code and documentation, is in the
- * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
- * </blockquote>
- *
- * <p>This class contains static methods for creating an XML reader
- * from an explicit class name, or for creating an XML reader based
- * on the value of the <code>org.xml.sax.driver</code> system 
- * property:</p>
- *
- * <pre>
- * try {
- *   XMLReader myReader = XMLReaderFactory.createXMLReader();
- * } catch (SAXException e) {
- *   System.err.println(e.getMessage());
- * }
- * </pre>
- *
- * <p>Note that these methods will not be usable in environments where
- * system properties are not accessible or where the application or
- * applet is not permitted to load classes dynamically.</p>
- *
- * <p><strong>Note to implementors:</strong> SAX implementations in specialized
- * environments may replace this class with a different one optimized for the
- * environment, as long as its method signatures remain the same.</p>
- *
- * @since SAX 2.0
- * @author David Megginson, 
- *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>
- * @version 2.0
- * @see org.xml.sax.XMLReader
- */
-final public class XMLReaderFactory
-{
-
-    /**
-     * Private constructor.
-     *
-     * <p>This constructor prevents the class from being instantiated.</p>
-     */
-    private XMLReaderFactory ()
-    {
-    }
-
-
-    /**
-     * Attempt to create an XML reader from a system property.
-     *
-     * <p>This method uses the value of the system property
-     * "org.xml.sax.driver" as the full name of a Java class
-     * and tries to instantiate that class as a SAX2 
-     * XMLReader.</p>
-     *
-     * <p>Note that many Java interpreters allow system properties
-     * to be specified on the command line.</p>
-     *
-     * @return A new XMLReader.
-     * @exception org.xml.sax.SAXException If the value of the
-     *            "org.xml.sax.driver" system property is null,
-     *            or if the class cannot be loaded and instantiated.
-     * @see #createXMLReader(java.lang.String)
-     */
-    public static XMLReader createXMLReader ()
-	throws SAXException
-    {
-	String className = System.getProperty("org.xml.sax.driver");
-	if (className == null) {
-	    Parser parser;
-	    try {
-		parser = ParserFactory.makeParser();
-	    } catch (Exception e) {
-		parser = null;
-	    }
-	    if (parser == null) {
-		throw new
-		    SAXException("System property org.xml.sax.driver not specified");
-	    } else {
-		return new ParserAdapter(parser);
-	    }
-	} else {
-	    return createXMLReader(className);
-	}
-    }
-
-
-    /**
-     * Attempt to create an XML reader from a class name.
-     *
-     * <p>Given a class name, this method attempts to load
-     * and instantiate the class as an XML reader.</p>
-     *
-     * @return A new XML reader.
-     * @exception org.xml.sax.SAXException If the class cannot be
-     *            loaded, instantiated, and cast to XMLReader.
-     * @see #createXMLReader()
-     */
-    public static XMLReader createXMLReader (String className)
-	throws SAXException
-    {
-	try {
-	    return (XMLReader)(Class.forName(className).newInstance());
-	} catch (ClassNotFoundException e1) {
-	    throw new SAXException("SAX2 driver class " + className +
-				   " not found", e1);
-	} catch (IllegalAccessException e2) {
-	    throw new SAXException("SAX2 driver class " + className +
-				   " found but cannot be loaded", e2);
-	} catch (InstantiationException e3) {
-	    throw new SAXException("SAX2 driver class " + className +
-				   " loaded but cannot be instantiated (no empty public constructor?)",
-				   e3);
-	} catch (ClassCastException e4) {
-	    throw new SAXException("SAX2 driver class " + className +
-				   " does not implement XMLReader", e4);
-	}
-				   
-    }
-
-}
-
-// end of XMLReaderFactory.java
diff --git a/src/whiteboard/org/apache/xerces/tree/AttributeListEx.java b/src/whiteboard/org/apache/xerces/tree/AttributeListEx.java
deleted file mode 100644
index 03b3cb7..0000000
--- a/src/whiteboard/org/apache/xerces/tree/AttributeListEx.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import org.xml.sax.AttributeList;
-
-
-/**
- * This interface extends the SAX AttributeList interface to expose
- * information needed to support DOM Level 1 features used in document
- * editing, and detection of ID attributes which are declared for
- * an element.
- *
- * @author David Brownell
- * @version $Revision$
- */
-public interface AttributeListEx extends AttributeList
-{
-    /**
-     * Returns true if the attribute was specified in the document.
-     * <em> This method only relates to document editing; there is no
-     * difference in semantics between explicitly specifying values
-     * of attributes in a DTD vs another part of the document. </em>
-     *
-     * @param i the index of the attribute in the list.
-     */
-    public boolean isSpecified (int i);
-
-    /**
-     * Returns the default value of the specified attribute, or null
-     * if no default value is known.  Default values may be explicitly
-     * specified in documents; in fact, for standalone documents, they
-     * must be so specified.  If <em>isSpecified</em> is false, the
-     * value returned by this method will be what <em>getValue</em>
-     * returns.
-     *
-     * @param i the index of the attribute in the list.
-     */
-    public String getDefault (int i);
-
-    /**
-     * Returns the name of the ID attribute for the associated element,
-     * if one was declared.  If such an ID value was provided, this
-     * name can be inferred from methods in the base class; but if none
-     * was provided, this will be the only way this name can be determined.
-     */
-    public String getIdAttributeName ();
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/AttributeNode.java b/src/whiteboard/org/apache/xerces/tree/AttributeNode.java
deleted file mode 100644
index f5fde3e..0000000
--- a/src/whiteboard/org/apache/xerces/tree/AttributeNode.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import java.io.Writer;
-import java.io.IOException;
-
-import org.w3c.dom.*;
-// Need to move this the xerces/util rather than having it here
-import org.apache.xerces.tree.XmlNames;
-
-/**
- * Node representing an XML attribute.  Many views of attributes can be
- * useful, but only the first of these is explicitly supported: <DL>
- *
- *	<DT> <em>Logical View</em> </DT><DD>  Attributes always hold a
- *	string created by expanding character and entity references from
- *	source text conforming to the XML specification.  If this
- *	attribute was declared in a DTD, normalization will often be
- *	done to eliminate insignificant whitespace.</DD>
- *
- *	<DT> <em>DTD Validated View</em> </DT><DD>  If the attribute was
- *	declared in a DTD, it will have minimal semantics provided by its
- *	declaration, and checked by validating parsers.  For example, the
- *	logical view may name one (or many) unparsed entities or DOM nodes.
- *	This view could provide direct access to them for any DTD, since
- *	these attribute semantics are defined by XML itself.</DD>
- *
- *	<DT> <em>Semantic View</em> </DT><DD> The person who wrote the
- *	DTD (or other namespace) defined what each attribute's logical
- *	view "means".  For example, that it's a URL, or that the unparsed
- *	entity referred to identifies a particular database to be used.
- *	This view would provide direct access to such values, but would
- *	need to have code specialized to that DTD or namespace.</DD>
- *
- *	<DT> <em>Physical View</em> </DT><DD>  Attributes may have children
- *	to represent text and entity reference nodes found in unexpanded
- *	and unnormalized XML source text.  Such views are mostly of interest
- *	when editing XML text that is not dynamically generated by programs.
- *	This implementation does not currently support physical views of
- *	attributes.  </DD>
- *
- *	</DL>
- *
- *
- * @author David Brownell
- * @author Rajiv Mordani
- * @version $Revision$
- */
-final	// at least for the moment
-// public
-class AttributeNode extends NamespacedNode
-    implements Attr, NamespaceScoped
-{
-    private String      value;
-    private boolean	specified;
-    private String	defaultValue;
-    private ElementNode ownerElement;
-
-    private ElementNode	nameScope;
-        
-    /** Constructs a copy of the specified node. */
-    public AttributeNode (AttributeNode original)
-    throws DOMException
-    {
-	this (original.name, original.value,
-		original.specified, original.defaultValue);
-	nameScope = original.nameScope;
-	setOwnerDocument ((XmlDocument) original.getOwnerDocument ());
-    }
-
-    /** Constructs an attribute node. */
-    public AttributeNode (String name, String value,
-	boolean specified, String defaultValue)
-    throws DOMException
-    {
-	if (!XmlNames.isName (name))
-	    throw new DomEx (DOMException.INVALID_CHARACTER_ERR);
-
-        this.name = name;
-        this.value = value;
-	this.specified = specified;
-	this.defaultValue = defaultValue;
-    }
-
-    /** Constructs an attribute node. Used for SAX2 and DOM2 */
-    public AttributeNode(String namespaceURI, String qualifiedName,
-                         String value, boolean specified, String defaultValue)
-        throws DOMException
-    {
-	if (!XmlNames.isName(qualifiedName)) {
-	    throw new DomEx(DOMException.INVALID_CHARACTER_ERR);
-        }
-
-        this.name = qualifiedName;
-        this.namespaceURI = namespaceURI;
-        this.value = value;
-	this.specified = specified;
-	this.defaultValue = defaultValue;
-    }
-
-    // package private
-    void setNameScope (ElementNode e)
-    {
-	if (e != null && nameScope != null)
-	    throw new IllegalStateException (getMessage ("A-000", 
-				     new Object [] { e.getTagName () }));
-	nameScope = e;
-    }
-
-    // package private
-    ElementNode getNameScope ()
-    {
-	return nameScope;
-    }
-
-    // package private
-    String getDefaultValue ()
-    {
-	return defaultValue;
-    }
-
-
-    public String getNamespace ()
-    {
-	if (nameScope == null)
-	    throw new IllegalStateException (getMessage ("A-001"));
-
-	String	prefix;
-	String	value;
-
-	
-	if ((prefix = getPrefix()) == null)
-	    return nameScope.getNamespace ();
-
-	if ("xml".equals (prefix) || "xmlns".equals (prefix))
-	    return null;
-	value = nameScope.getInheritedAttribute ("xmlns:" + prefix);
-
-	if (value == null)
-	    throw new IllegalStateException ();
-
-	return value;
-    }
-
-    
-    /**
-     * <b>DOM2:</b>
-     */
-    public Element getOwnerElement() {
-        return ownerElement;
-    }
-
-    void setOwnerElement(ElementNode element) {
-        ownerElement = element;
-    }
-
-    
-    /** DOM:  Returns the ATTRIBUTE_NODE node type constant. */
-    public short getNodeType () { return ATTRIBUTE_NODE; }
-
-    /** DOM:  Returns the attribute name */
-    public String getName () { return name; }
-
-    /** DOM:  Returns the attribute name */
-    public String getNodeName () { return name; }
-
-    /** DOM:  Returns the attribute value. */
-    public String getValue () { return value; }
-
-    /** DOM:  Assigns the value of this attribute. */
-    public void setValue (String value) { setNodeValue (value); }
-
-    /** DOM:  Returns the attribute value. */
-    public String getNodeValue () { return value; }
-
-    /** DOM:  Returns true if the source text specified the attribute. */
-    public boolean getSpecified () { return specified; }
-
-    /** DOM:  Assigns the value of this attribute. */
-    public void setNodeValue (String value)
-    {
-    	if (isReadonly ())
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-	this.value = value;
-	specified = true;
-    }
-
-    /** Flags whether the source text specified the attribute. */
-    // pubic
-    void setSpecified (boolean specified) { this.specified = specified; }
-
-    /** DOM:  Returns null */
-    public Node getParentNode () { return null; }
-    
-    /** DOM:  Returns null */
-    public Node getNextSibling () { return null; }
-    
-    /** DOM:  Returns null */
-    public Node getPreviousSibling () { return null; }
-
-    
-    /**
-     * Writes the attribute out, as if it were assigned within an
-     * element's starting tag (<em>name="value"</em>).
-     */
-    public void writeXml (XmlWriteContext context) throws IOException
-    {
-	Writer	out = context.getWriter ();
-
-        out.write (name);
-	out.write ("=\"");
-	writeChildrenXml (context);
-	out.write ('"');
-    }
-
-    /**
-     * Writes the attribute's value.
-     */
-    public void writeChildrenXml (XmlWriteContext context) throws IOException
-    {
-	Writer	out = context.getWriter ();
-	for (int i = 0; i < value.length (); i++) {
-	    int c = value.charAt (i);
-	    switch (c) {
-	      // XXX only a few of these are necessary; we
-	      // do what "Canonical XML" expects
-	      case '<':  out.write ("&lt;"); continue;
-	      case '>':  out.write ("&gt;"); continue;
-	      case '&':  out.write ("&amp;"); continue;
-	      case '\'': out.write ("&apos;"); continue;
-	      case '"':  out.write ("&quot;"); continue;
-	      default:   out.write (c); continue;
-	    }
-	}
-    }
-
-    /** DOM: returns a copy of this node */
-    public Node cloneNode (boolean deep)
-    {
-
-	try {
-		AttributeNode attr = new AttributeNode (this.name, this.value,
-			this.specified, this.defaultValue);
-		attr.setOwnerDocument ((XmlDocument)this.getOwnerDocument ());
-		attr.ownerElement = ownerElement;
-		if (deep) {
-	            Node	node;
-
-	            for (int i = 0; (node = item (i)) != null; i++) {
-		        node = node.cloneNode (true);
-		        attr.appendChild (node);
-	            }
-		}
-		return attr;
-	} catch (DOMException e) {
-	    throw new RuntimeException (getMessage ("A-002"));
-	}
-    }
-
-    void checkChildType(int type) throws DOMException {
-	switch(type) {
-	  case TEXT_NODE:
-	  case ENTITY_REFERENCE_NODE:
-	    return;
-	  default:
-	    throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	}
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/AttributeSet.java b/src/whiteboard/org/apache/xerces/tree/AttributeSet.java
deleted file mode 100644
index 66cfba0..0000000
--- a/src/whiteboard/org/apache/xerces/tree/AttributeSet.java
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-
-import java.io.CharArrayWriter;
-import java.io.Writer;
-import java.io.IOException;
-import java.util.Vector;
-
-import org.w3c.dom.*;
-
-import org.xml.sax.AttributeList;
-import org.xml.sax.Attributes;
-//import org.xml.sax.Attr;
-
-// Should move to use the xerces sax2 Attribute impl
-import org.apache.xerces.tree.AttributeListEx;
-
-
-/**
- * Class representing an XML attribute list.
- *
- * <P> This couples slightly with the Sun XML parser, in that it optionally
- * uses an extended SAX 1.0 API to see if an attribute was specified in the
- * document or was instead defaulted by attribute processing.
- *
- * @author David Brownell
- * @version $Revision$
- */
-final
-class AttributeSet implements NamedNodeMap, XmlWritable
-{
-    private boolean	readonly;
-    private Vector	list;
-    private ElementNode	nameScope;
-        
-    /* Constructs an attribute list, with associated name scope. */
-    // package private
-    AttributeSet (ElementNode nameScope)
-    {
-	list = new Vector (5);
-	this.nameScope = nameScope;
-    }
-
-    /*
-     * Constructs a copy of an attribute list, for use in cloning.
-     * name scopes are set separately.
-     */
-    // package private
-    AttributeSet (AttributeSet original, boolean deep)
-    {
-	int		size = original.getLength ();
-
-	list = new Vector (size);
-	for (int i = 0; i < size; i++) {
-	    Node	node = original.item (i);
-
-	    if (!(node instanceof AttributeNode))
-		throw new IllegalArgumentException (((NodeBase)node).
-						getMessage ("A-003"));
-	    node = node.cloneNode (deep);
-
-	    // temporarily undo binding to element ... it's rebound
-	    // by the caller
-	    ((AttributeNode)node).setNameScope (null);
-	    list.addElement (node);
-	}
-    }
-
-    // package private
-    AttributeSet (AttributeList source)
-    throws DOMException
-    {
-	int			len = source.getLength ();
-	AttributeListEx		ex = null;
-
-	list = new Vector (len);
-	if (source instanceof AttributeListEx)
-	    ex = (AttributeListEx) source;
-
-	for (int i = 0; i < len; i++) {
-	    list.addElement (new AttributeNode (
-		    source.getName (i),
-		    source.getValue (i),
-		    ex == null	// remember if it was specified
-			? true
-			: ex.isSpecified (i),
-		    ex == null	// remember any default value
-			? null
-			: ex.getDefault (i)
-		    ));
-	}
-	list.trimToSize ();
-    }
-
-    /**
-     * <b>DOM2:</b> Create DOM NamedNodeMap from SAX2 Attributes object
-     */
-    AttributeSet(Attributes source) throws DOMException {
-	int			len = source.getLength();
-	AttributeListEx		ex = null;
-
-	list = new Vector(len);
-	if (source instanceof AttributeListEx) { // XXX fix this
-	    ex = (AttributeListEx) source;
-        }
-
-	for (int i = 0; i < len; i++) {
-            // Translate "" of SAX2 to null.  See DOM2 spec under Node
-            // namespaceURI
-            String uri = source.getURI(i);
-            if (uri.equals("")) {
-                uri = null;
-            }
-
-            AttributeNode attrNode =
-                new AttributeNode(uri,
-                                  source.getQName(i),
-                                  source.getValue(i),
-                                  ex == null	// remember if it was specified
-                                  ? true
-                                  : ex.isSpecified(i),
-                                  ex == null	// remember any default value
-                                  ? null
-                                  : ex.getDefault(i));
-	    list.addElement(attrNode);
-	}
-	list.trimToSize();
-    }
-
-    // package private
-    void trimToSize () { list.trimToSize (); }
-
-    // package private
-    public void setReadonly ()
-    {
-	readonly = true;
-	for (int i = 0; i < list.size (); i++)
-	    ((AttributeNode)list.elementAt (i)).setReadonly (true);
-    }
-
-    public boolean isReadonly () {
-    	if (readonly)
-	    return true;
-	for (int i = 0; i < list.size (); i++) {
-	    if (((AttributeNode)list.elementAt (i)).isReadonly ()) {
-	   	return true; 
-	    }
-	}
-	return false;
-    }
-
-    // package private
-    void setNameScope (ElementNode e)
-    {
-	if (e != null && nameScope != null)
-	    throw new IllegalStateException (e.getMessage ("A-004"));
-	nameScope = e;
-
-	// need to bind the attributes to this element
-	int	length = list.size ();
-
-	for (int i = 0; i < length; i++) {
-	    AttributeNode	node;
-
-	    node = (AttributeNode) list.elementAt (i);
-	    node.setNameScope (null);
-	    node.setNameScope (e);
-	}
-    }
-
-    // package private
-    ElementNode getNameScope ()
-    {
-	return nameScope;
-    }
-
-
-    // package private
-    String getValue (String name)
-    {
-	Attr	attr = (Attr) getNamedItem (name);
-
-	if (attr == null)
-	    return "";
-	else
-	    return attr.getValue ();
-    }
-
-    public Node getNamedItem (String name)
-    {
-	int	length = list.size ();
-	Node	value;
-
-	for (int i = 0; i < length; i++) {
-	    value = item (i);
-	    if (value.getNodeName ().equals (name))
-		return value;
-	}
-	return null;
-    }
-
-    /**
-     * <b>DOM2:</b>
-     */
-    public Node getNamedItemNS(String namespaceURI, String localName) {
-	for (int i = 0; i < list.size(); i++) {
-	    Node value = item(i);
-            String iLocalName = value.getLocalName();
-	    if (iLocalName != null && iLocalName.equals(localName)) {
-                String iNamespaceURI = value.getNamespaceURI();
-                if (iNamespaceURI != null
-                    && iNamespaceURI.equals(namespaceURI)) {
-                    return value;
-                }
-            }
-	}
-	return null;
-    }
-
-    public int getLength ()
-    {
-	return list.size ();
-    }
-
-    public Node item (int index)
-    {
-	if (index < 0 || index >= list.size ())
-	    return null;
-	return (Node) list.elementAt (index);
-    }
-
-    public Node removeNamedItem (String name)
-    throws DOMException
-    {
-	int		length = list.size ();
-	Node		value;
-
-	if (readonly)
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-	for (int i = 0; i < length; i++) {
-	    value = item (i);
-	    if (value.getNodeName ().equals (name)) {
-		AttributeNode	att = (AttributeNode) value;
-
-		if (att.getDefaultValue () != null) {
-		    att = new AttributeNode (att);
-		    att.setOwnerDocument ((XmlDocument)
-			    nameScope.getOwnerDocument ());
-		    list.setElementAt (att, i);
-		} else
-		    list.removeElementAt (i);
-
-		att.setNameScope (null);
-		return value;
-	    }
-	}
-	throw new DomEx (DomEx.NOT_FOUND_ERR);
-    }
-
-    /**
-     * <b>DOM2:</b>
-     */
-    public Node removeNamedItemNS(String namespaceURI, String localName)
-        throws DOMException
-    {
-	if (readonly) {
-	    throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
-        }
-
-	for (int i = 0; i < list.size(); i++) {
-	    Node value = item(i);
-            String iLocalName = value.getLocalName();
-	    if (iLocalName != null && iLocalName.equals(localName)) {
-                String iNamespaceURI = value.getNamespaceURI();
-                if (iNamespaceURI != null
-                    && iNamespaceURI.equals(namespaceURI)) {
-                    AttributeNode attr = (AttributeNode) value;
-                    if (attr.getDefaultValue() != null) {
-                        attr = new AttributeNode(attr);
-                        list.setElementAt(attr, i);
-                    } else {
-                        list.removeElementAt(i);
-                    }
-                    return value;
-                }
-            }
-	}
-	throw new DomEx(DomEx.NOT_FOUND_ERR);
-    }
-
-    public Node setNamedItem (Node value)
-    throws DOMException
-    {
-	AttributeNode	node;
-
-	if (readonly)
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-	if (!(value instanceof AttributeNode)
-		|| value.getOwnerDocument ()
-			!= nameScope.getOwnerDocument ())
-	    throw new DomEx (DomEx.WRONG_DOCUMENT_ERR);
-	node = (AttributeNode)value;
-	if (node.getNameScope () != null)
-	    throw new DomEx (DomEx.INUSE_ATTRIBUTE_ERR);
-
-	int		length = list.size ();
-	AttributeNode	oldValue;
-
-	for (int i = 0; i < length; i++) {
-	    oldValue = (AttributeNode) item (i);
-	    if (oldValue.getNodeName ().equals (value.getNodeName ())) {
-	    	if (oldValue.isReadonly ())
-	    	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-		node.setNameScope (nameScope);
-		list.setElementAt (value, i);
-		oldValue.setNameScope (null);
-		return oldValue;
-	    }
-	}
-	node.setNameScope (nameScope);
-	list.addElement (value);
-	return null;
-    }
-    
-    /**
-     * <b>DOM2:</b>
-     * XXX spec allows Element nodes also, but this code assumes Attr nodes
-     * only
-     */
-    public Node setNamedItemNS(Node arg) throws DOMException {
-	if (readonly) {
-	    throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
-        }
-
-	AttributeNode attr = (AttributeNode) arg;
-        if (attr.getOwnerElement() != null) {
-	    throw new DomEx(DomEx.INUSE_ATTRIBUTE_ERR);
-        }
-
-	for (int i = 0; i < list.size(); i++) {
-	    AttributeNode oldNode = (AttributeNode) item(i);
-            String localName = oldNode.getLocalName();
-            String namespaceURI = oldNode.getNamespaceURI();
-            if (arg.getLocalName().equals(localName)
-                && arg.getNamespaceURI().equals(namespaceURI)) {
-                // Found a matching node so replace it
-                list.setElementAt(arg, i);
-                return oldNode;
-            }
-	}
-
-        // Append instead of replace
-	list.addElement(arg);
-	return null;
-    }
-
-    /**
-     * Writes out the attribute list.  Attributes known to have been
-     * derived from the DTD are not (at this time) written out.  Part
-     * of writing standalone XML is first ensuring that all attributes
-     * are flagged as being specified in the "printed" form (or else
-     * are defaulted only in the internal DTD subset).
-     */
-    public void writeXml (XmlWriteContext context) throws IOException
-    {
-	Writer		out = context.getWriter ();
-	int		length = list.size ();
-	AttributeNode	tmp;
-
-	for (int i = 0; i < length; i++) {
-	    tmp = (AttributeNode) list.elementAt (i);
-	    if (tmp.getSpecified ()) {
-		out.write (' ');
-		tmp.writeXml (context);
-	    }
-	}
-    }
-
-    /**
-     * Does nothing; this type of node has no children.
-     */
-    public void writeChildrenXml (XmlWriteContext context) throws IOException
-    {
-    }
-
-    public String toString ()
-    {
-	try {
-	    CharArrayWriter w = new CharArrayWriter ();
-	    XmlWriteContext x = new XmlWriteContext (w);
-	    writeXml (x);
-	    return w.toString ();
-
-	} catch (IOException e) {
-	    return super.toString ();
-	}
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/CDataNode.java b/src/whiteboard/org/apache/xerces/tree/CDataNode.java
deleted file mode 100644
index 01421bf..0000000
--- a/src/whiteboard/org/apache/xerces/tree/CDataNode.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-
-import java.io.Writer;
-import java.io.IOException;
-
-import org.w3c.dom.*;
-
-
-/**
- * Node representing XML CDATA text, which is just like other text except
- * for its delimiters (<em>&lt;[CDATA[</em>text<em>]]&gt;</em>).  CDATA
- * is used to embed markup, program source code, and other kinds of text
- * that use XML markup delimiters (<em>&lt;</em> and <em>&amp;</em>) for
- * their own nefarious purposes.
- *
- * @author David Brownell
- * @version $Revision$
- */
-//public
-class CDataNode extends TextNode implements CDATASection
-{
-    /**
-     * Constructs a CDATA text object with no text.
-     */
-    public CDataNode () { }
-
-        
-    /**
-     * Constructs CDATA text object by copying text from the input buffer.
-     */
-    public CDataNode (char buf [], int offset, int len)
-    {
-	super (buf, offset, len);
-    }
-
-    /**
-     * Constructs a CDATA text object by copying text from the string.
-     */
-    public CDataNode (String s)
-    {
-	super (s);
-    }
-
-    /**
-     * Writes the text, breaking this into multiple CDATA sections
-     * if necessary to escape <em>[[&lt;</em> in the data.
-     */
-    public void writeXml (XmlWriteContext context) throws IOException
-    {
-	Writer	out = context.getWriter ();
-	out.write ("<![CDATA[");
-	for (int i = 0; i < data.length; i++) {
-	    char c = data [i];
-
-	    // embedded "]]>" needs to be split into adjacent
-	    // CDATA blocks ... can be split at either point
-	    if (c == ']') {
-		if ((i + 2) < data.length
-			&& data [i + 1] == ']'
-			&& data [i + 2] == '>') {
-		    out.write ("]]]]><![CDATA[>");
-		    continue;
-		}
-	    }
-	    out.write (c);
-	}
-	out.write ("]]>");
-    }
-
-    // DOM support
-
-    /** DOM: Returns the CDATA_SECTION_NODE node type constant. */
-    public short getNodeType () { return CDATA_SECTION_NODE; }
-
-    /** Returns a new CDATA section with the same content as this. */
-    public Node cloneNode (boolean deep)
-    {
-    	CDataNode retval = new CDataNode (data, 0, data.length);
-	retval.setOwnerDocument ((XmlDocument)this.getOwnerDocument ());
-	return retval;
-    }
-
-    /** Returns the string "#cdata-section".*/
-    public String getNodeName () { return "#cdata-section"; }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/CommentNode.java b/src/whiteboard/org/apache/xerces/tree/CommentNode.java
deleted file mode 100644
index 93ac778..0000000
--- a/src/whiteboard/org/apache/xerces/tree/CommentNode.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-
-import java.io.Writer;
-import java.io.IOException;
-
-import org.w3c.dom.*;
-
-
-/**
- * Class representing an XML Comment.
- *
- * @author David Brownell
- * @version $Revision$
- */
-// public
-class CommentNode extends DataNode implements Comment
-{
-    /** Constructs a comment node. */
-    public CommentNode () { }
-
-    /** Constructs a comment node. */
-    public CommentNode (String data)
-    {
-        super (data);
-    }
-
-    CommentNode (char buf [], int offset, int len)
-	{ super (buf, offset, len); }
-    
-    /** DOM:  Returns the COMMENT_NODE node type. */
-    public short getNodeType () { return COMMENT_NODE; }
-
-
-    /**
-     * Writes out the comment.  Note that spaces may be added to
-     * prevent illegal comments:  between consecutive dashes ("--")
-     * or if the last character of the comment is a dash.
-     */
-    public void writeXml (XmlWriteContext context) throws IOException
-    {
-	Writer	out = context.getWriter ();
-        out.write ("<!--");
-        if (data != null) {
-	    boolean	sawDash = false;
-	    int		length = data.length;
-
-	    // "--" illegal in comments, expand it
-	    for (int i = 0; i < length; i++) {
-		if (data [i] == '-') {
-		    if (sawDash)
-			out.write (' ');
-		    else {
-			sawDash = true;
-			out.write ('-');
-			continue;
-		    }
-		}
-		sawDash = false;
-		out.write (data [i]);
-	    }
-	    if (data [data.length - 1] == '-')
-		out.write (' ');
-	}
-        out.write ("-->");
-    }
-
-    /** Returns a new comment with the same content as this. */
-    public Node cloneNode (boolean deep) { 
-    	CommentNode retval = new CommentNode (data, 0, data.length); 
-	retval.setOwnerDocument ((XmlDocument) this.getOwnerDocument ());
-    	return retval;
-    }
-
-    /** Returns the string "#comment". */
-    public String getNodeName () { return "#comment"; }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/DataNode.java b/src/whiteboard/org/apache/xerces/tree/DataNode.java
deleted file mode 100644
index 8f9b637..0000000
--- a/src/whiteboard/org/apache/xerces/tree/DataNode.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-
-import java.io.Writer;
-import java.io.IOException;
-
-import org.w3c.dom.*;
-
-
-/**
- * Node representing XML character data, such as text (including
- * CDATA sections and comments).
- *
- * <P> At this time this uses an unsophisticated representation
- * which is not suited for complex editing operations.
- *
- * @author David Brownell
- * @version $Revision$
- */
-// public
-abstract class DataNode extends NodeBase implements CharacterData
-{
-    // package private
-    char        	data [];
-    static NodeListImpl childNodes = new NodeListImpl ();
-
-    /*
-     * Constructs a data object with no text and unattached
-     * to any document.
-     */
-    DataNode () { }
-
-        
-    /*
-     * Constructs data node by copying text from the input buffer.
-     */
-    DataNode (char buf [], int offset, int len)
-    {
-        data = new char [len];
-        System.arraycopy (buf, offset, data, 0, len);
-    }
-
-    /*
-     * Constructs a data node by copying text from the string.
-     */
-    DataNode (String s)
-    {
-	if (s != null) {
-	    data = new char [s.length ()];
-	    s.getChars (0, data.length, data, 0);
-	} else
-	    data = new char [0];
-    }
-
-    /**
-     * Returns the text of the node. This may be modified by
-     * the caller only if the length remains unchanged.
-     */
-    public char [] getText () { return data; }
-
-    /**
-     * Assigns the text of the node.  The buffer is consumed; the
-     * caller should make copies accordingly.
-     */
-    public void setText (char buf []) { data = buf; }
-
-    /**
-     * Returns the contents of this text as a String.
-     */
-    public String toString () { return new String (data); }
-    
-
-
-    // DOM support
-
-    /** DOM: Returns the text data as a string. */
-    public String getData () { return toString (); }
-
-    /** DOM: Assigns the text data. */
-    public void setData (String data) { 
-        if (isReadonly ())
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-
-	if (data == null) {
-	    setText (new char [0]);
-	} else {
-	    setText (data.toCharArray ()); 
-	}
-    }
-
-    /** DOM:  Returns the length of the node's data. */
-    public int getLength ()
-	{ return data == null ? 0 : data.length; }
-
-    /**
-     * DOM:  Returns the specified substring of the data in this node.
-     */
-    public String substringData (int offset, int count)
-    throws DOMException
-    {
-	if (offset < 0 || offset > data.length || count < 0)
-	    throw new DomEx (DOMException.INDEX_SIZE_ERR);
-
-	count = Math.min (count, data.length - offset);
-	return new String (data, offset, count);
-    }
-
-    /**
-     * DOM: Appends the string to the existing stored data.
-     */
-    public void appendData (String newData)
-    {
-        if (isReadonly ())
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-	int	length = newData.length ();
-	char	tmp [] = new char [length + data.length];
-
-	System.arraycopy (data, 0, tmp, 0, data.length);
-	newData.getChars (0, length, tmp, data.length);
-	data = tmp;
-    }
-
-    /**
-     * DOM: Inserts the given data into the existing stored data
-     * at the specified offset.
-     */
-    public void insertData (int offset, String newData)
-    throws DOMException
-    {
-        if (isReadonly ())
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-
-	if (offset < 0 || offset >= data.length)
-	    throw new DomEx (DOMException.INDEX_SIZE_ERR);
-
-	int	length = newData.length ();
-	char	tmp [] = new char [length + data.length];
-
-	System.arraycopy (data, 0, tmp, 0, offset);
-	newData.getChars (0, length, tmp, offset);
-	System.arraycopy (data, offset,
-	    tmp, offset + length,
-	    data.length - offset);
-	data = tmp;
-    }
-
-    /**
-     * DOM: Removes a range of characters from the text.
-     */
-    public void deleteData (int offset, int count)
-    throws DOMException
-    {
-	char	tmp [];
-
-        if (isReadonly ())
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-
-	if (offset < 0 || offset >= data.length || count < 0)
-	    throw new DomEx (DOMException.INDEX_SIZE_ERR);
-	count = Math.min (count, data.length - offset);
-
-	tmp = new char [data.length - count];
-	System.arraycopy (data, 0, tmp, 0, offset);
-	System.arraycopy (data, offset + count, tmp, offset,
-			  tmp.length - offset);
-	data = tmp;
-    }
-
-    /**
-     * DOM: Replaces <em>count</em> characters starting at the specified
-     * <em>offset</em> in the data with the characters from the
-     * specified <em>arg</em>.
-     */
-    public void replaceData (int offset, int count, String arg)
-    throws DOMException
-    {
-        if (isReadonly ())
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-
-	if (offset < 0 || offset >= data.length || count < 0)
-	    throw new DomEx (DOMException.INDEX_SIZE_ERR);
-
-	if ((offset + count) >= data.length) {
-	    deleteData (offset, count);
-	    appendData (arg);
-	} else if (arg.length () == count) {
-	    arg.getChars (0, (arg.length ()), data, offset);
-	} else {
-	    char tmp [] = new char [data.length + (arg.length () - count)];
-	    System.arraycopy (data, 0, tmp, 0, offset);
-	    arg.getChars (0, (arg.length ()), tmp, offset);
-	    System.arraycopy (data, (offset + count), tmp, (offset +
-	    		      arg.length ()), data.length -(offset + count));
-	    data = tmp;
-	}
-    }
-
-    /**
-     * DOM:  Returns the children of this node.
-     */
-    public NodeList getChildNodes () { return childNodes; }
-
-    /**
-     * DOM:  Returns the node's character data.
-     */
-    public String getNodeValue () { return getData (); }
-
-    /**
-     * DOM:  Assigns the node's character data.
-     */
-    public void setNodeValue (String value) { setData (value); }
-
-    static final class NodeListImpl implements NodeList {
-   	public Node item (int i) { return null;}
-	public int getLength () { return 0;}
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/Doctype.java b/src/whiteboard/org/apache/xerces/tree/Doctype.java
deleted file mode 100644
index 0797fc4..0000000
--- a/src/whiteboard/org/apache/xerces/tree/Doctype.java
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-
-import java.io.OutputStreamWriter;
-import java.io.OutputStream;
-import java.io.Writer;
-import java.io.IOException;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-import org.w3c.dom.*;
-
-import org.xml.sax.SAXException;
-
-//Don't need this looks like.
-//import org.apache.crimson.parser.Parser;
-
-
-/**
- * Class representing a DTD in DOM Level 1; this class exists purely
- * for editor support, and is of dubious interest otherwise.
- *
- * @author David Brownell
- * @version $Revision$
- */
-final class Doctype extends NodeBase implements DocumentType
-{
-    // Stuff generated during parsing ...
-    private String	name;
-    private Nodemap	entities;
-    private Nodemap	notations;
-
-    // ... stuff assigned by apps separately
-    private String	publicId;
-    private String	systemId;
-    private String	internalSubset;
-
-
-    // package private
-    Doctype (String n)
-    {
-	name = n;
-	entities = new Nodemap ();
-	notations = new Nodemap ();
-    }
-
-    // package private
-    Doctype (String pub, String sys, String subset)
-    {
-	publicId = pub;
-	systemId = sys;
-	internalSubset = subset;
-    }
-
-    // package private
-    Doctype(String name, String publicId, String systemId,
-            String internalSubset)
-    {
-        this.name = name;
-        this.publicId = publicId;
-	this.systemId = systemId;
-	this.internalSubset = internalSubset;
-    }
-
-    // package private
-    void setPrintInfo (String pub, String sys, String subset)
-    {
-	publicId = pub;
-	systemId = sys;
-	internalSubset = subset;
-    }
-
-
-    /**
-     * Writes out a textual DTD, trusting that any internal subset text
-     * is in fact well formed XML.
-     */
-    public void writeXml (XmlWriteContext context) throws IOException
-    {
-	Writer	out = context.getWriter ();
-	Element	root = getOwnerDocument ().getDocumentElement ();
-
-	out.write ("<!DOCTYPE ");
-	out.write (root == null ? "UNKNOWN-ROOT" : root.getNodeName ());
-
-	if (systemId != null) {
-	    if (publicId != null) {
-		out.write (" PUBLIC '");
-		out.write (publicId);
-		out.write ("' '");
-	    } else
-		out.write (" SYSTEM '");
-	    out.write (systemId);
-	    out.write ("'");
-	}
-	if (internalSubset != null) {
-	    out.write (XmlDocument.eol);
-	    out.write ("[");
-	    out.write (internalSubset);
-	    out.write ("]");
-	}
-	out.write (">");
-	out.write (XmlDocument.eol);
-    }
-
-    /** DOM: Returns DOCUMENT_TYPE_NODE */
-    public short getNodeType ()
-	{ return DOCUMENT_TYPE_NODE; }
-    
-    /** DOM:  Returns the name declared for the document root node. */
-    public String getName ()
-	{ return name; }
-    
-    /** DOM:  Returns the name declared for the document root node. */
-    public String getNodeName ()
-	{ return name; }
-    
-    /** DOM: NYI
-     * @deprecated Not yet implemented.
-     */
-    public Node cloneNode (boolean deep)
-    {
-// XXX
-	throw new RuntimeException (getMessage ("DT-000"));
-    }
-
-    /**
-     * DOM: Returns the internal, external, and unparsed entities
-     * declared in this DTD.
-     */
-    public NamedNodeMap getEntities ()
-	{ return entities; }
-
-    /** DOM: Returns the notations declared in this DTD.  */
-    public NamedNodeMap getNotations ()
-	{ return notations; }
-    
-    /**
-     * The public identifier of the external subset.
-     * @since DOM Level 2
-     */
-    public String getPublicId() {
-        return publicId;
-    }
-
-    /**
-     * The system identifier of the external subset.
-     * @since DOM Level 2
-     */
-    public String getSystemId() {
-        return systemId;
-    }
-
-    /**
-     * The internal subset as a string.
-     * @since DOM Level 2
-     */
-    public String getInternalSubset() {
-        return internalSubset;
-    }
-
-    // package private
-    void setOwnerDocument (XmlDocument doc)
-    {
-	super.setOwnerDocument (doc);
-	if (entities != null)
-	    for (int i = 0; entities.item (i) != null; i++)
-		((NodeBase)entities.item (i)).setOwnerDocument (doc);
-	if (notations != null)
-	    for (int i = 0; notations.item (i) != null; i++)
-		((NodeBase)notations.item (i)).setOwnerDocument (doc);
-    }
-
-
-    /** Adds a notation node. */
-    // package private
-    void addNotation (String name, String pub, String sys)
-    {
-	NotationNode node = new NotationNode (name, pub, sys);
-	node.setOwnerDocument ((XmlDocument)getOwnerDocument ());
-	notations.setNamedItem (node);
-    }
-
-    /**
-     * Adds an entity node for an external entity, which
-     * could be parsed or unparsed.
-     */
-    // package private
-    void addEntityNode (String name, String pub, String sys, String not)
-    {
-	EntityNode node = new EntityNode (name, pub, sys, not);
-	node.setOwnerDocument ((XmlDocument)getOwnerDocument ());
-	entities.setNamedItem (node);
-    }
-
-    /** Adds an entity node for an  internal parsed entity. */
-    // package private
-    void addEntityNode (String name, String value)
-    {
-	if ("lt".equals (name) || "gt".equals (name)
-		|| "apos".equals (name) || "quot".equals (name)
-		|| "amp".equals (name))
-	    return;	// predeclared, immutable
-
-	EntityNode node = new EntityNode (name, value);
-	node.setOwnerDocument ((XmlDocument)getOwnerDocument ());
-	entities.setNamedItem (node);
-    }
-
-    /** Marks the sets of entities and notations as readonly. */
-    // package private
-    void setReadonly ()
-    {
-	entities.readonly = true;
-	notations.readonly = true;
-    }
-
-
-    static class NotationNode extends NodeBase implements Notation
-    {
-	private String	notation;
-	private String	publicId;
-	private String	systemId;
-
-	NotationNode (String name, String pub, String sys)
-	{
-	    notation = name;
-	    publicId = pub;
-	    systemId = sys;
-	}
-
-	public String getPublicId ()
-	    { return publicId; }
-
-	public String getSystemId ()
-	    { return systemId; }
-	
-	public short getNodeType ()
-	    { return NOTATION_NODE; }
-	
-	public String getNodeName ()
-	    { return notation; }
-	
-	public Node cloneNode (boolean ignored)
-	{
-	    NotationNode retval;
-
-	    retval = new NotationNode (notation, publicId, systemId);
-	    retval.setOwnerDocument ((XmlDocument)getOwnerDocument ());
-	    return retval;
-	}
-
-	public void writeXml (XmlWriteContext context) throws IOException
-	{
-	    Writer out = context.getWriter ();
-	    out.write ("<!NOTATION ");
-	    out.write (notation);
-	    if (publicId != null) {
-		out.write (" PUBLIC '");
-		out.write (publicId);
-		if (systemId != null) {
-		    out.write ("' '");
-		    out.write (systemId);
-		}
-	    } else {
-		out.write (" SYSTEM '");
-		out.write (systemId);
-	    }
-	    out.write ("'>");
-	}
-    }
-
-
-    // DOM permits the children to be null ... we do that consistently
-    static class EntityNode extends NodeBase implements Entity
-    {
-	private String	entityName;
-
-	private String	publicId;
-	private String	systemId;
-	private String	notation;
-
-	private String	value;
-
-	EntityNode (String name, String pub, String sys, String not)
-	{
-	    entityName = name;
-	    publicId = pub;
-	    systemId = sys;
-	    notation = not;
-	}
-
-	EntityNode (String name, String value)
-	{
-	    entityName = name;
-	    this.value = value;
-	}
-
-	public String getNodeName ()
-	    { return entityName; }
-	
-	public short getNodeType ()
-	    { return ENTITY_NODE; }
-
-	public String getPublicId ()
-	    { return publicId; }
-
-	public String getSystemId ()
-	    { return systemId; }
-
-	public String getNotationName ()
-	    { return notation; }
-	
-	public Node cloneNode (boolean ignored)
-	{
-	    EntityNode retval;
-
-	    retval = new EntityNode (entityName, publicId, systemId,
-			    notation);
-	    retval.setOwnerDocument ((XmlDocument)getOwnerDocument ());
-	    return retval;
-	}
-
-	public void writeXml (XmlWriteContext context) throws IOException
-	{
-	    Writer out = context.getWriter ();
-	    out.write ("<!ENTITY ");
-	    out.write (entityName);
-
-	    if (value == null) {
-		if (publicId != null) {
-		    out.write (" PUBLIC '");
-		    out.write (publicId);
-		    out.write ("' '");
-		} else
-		    out.write (" SYSTEM '");
-		out.write (systemId);
-		out.write ("'");
-		if (notation != null) {
-		    out.write (" NDATA ");
-		    out.write (notation);
-		}
-	    } else {
-		out.write (" \"");
-		int length = value.length ();
-		for (int i = 0; i < length; i++) {
-		    char c = value.charAt (i);
-		    if (c == '"')
-			out.write ("&quot;");
-		    else
-			out.write (c);
-		}
-		out.write ('"');
-	    }
-	    out.write (">");
-	}
-    }
-
-    static class Nodemap implements NamedNodeMap
-    {
-	// package private
-	boolean	readonly;
-
-	// package private
-	java.util.Vector	list = new java.util.Vector ();
-
-	// XXX copied from AttributeSet; share implementation!
-	public Node getNamedItem (String name)
-	{
-	    int	length = list.size ();
-	    Node	value;
-
-	    for (int i = 0; i < length; i++) {
-		value = item (i);
-		if (value.getNodeName ().equals (name))
-		    return value;
-	    }
-	    return null;
-	}
-
-        /**
-         * <b>DOM2:</b>
-         */
-        public Node getNamedItemNS(String namespaceURI, String localName) {
-            return null;
-        }
-        
-	// XXX copied from AttributeSet; share implementation!
-	public int getLength ()
-	{
-	    return list.size ();
-	}
-
-	// XXX copied from AttributeSet; share implementation!
-	public Node item (int index)
-	{
-	    if (index < 0 || index >= list.size ())
-		return null;
-	    return (Node) list.elementAt (index);
-	}
-
-
-	public Node removeNamedItem (String name)
-	throws DOMException
-	{
-	    throw new DomEx (DOMException.NO_MODIFICATION_ALLOWED_ERR);
-	}
-
-        /**
-         * <b>DOM2:</b>
-         */
-        public Node removeNamedItemNS(String namespaceURI, String localName)
-            throws DOMException
-        {
-	    throw new DomEx(DOMException.NO_MODIFICATION_ALLOWED_ERR);
-        }
-
-	// caller guarantees (e.g. from parser) uniqueness
-	public Node setNamedItem (Node item) throws DOMException
-	{
-	    if (readonly)
-		throw new DomEx (DOMException.NO_MODIFICATION_ALLOWED_ERR);
-	    list.addElement (item);
-	    return null;
-	}
-
-        /**
-         * <b>DOM2:</b>
-         */
-        public Node setNamedItemNS(Node arg) throws DOMException {
-            if (readonly) {
-                throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
-            }
-
-            list.addElement(arg);
-            return null;
-        }
-
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/DocumentEx.java b/src/whiteboard/org/apache/xerces/tree/DocumentEx.java
deleted file mode 100644
index adce1cd..0000000
--- a/src/whiteboard/org/apache/xerces/tree/DocumentEx.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import java.util.Locale;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-
-/**
- * This interface extends the DOM Document model in several useful ways.
- * It supports:  <UL>
- *
- * <LI> Application-specialized element creation and document customization
- *	at parse time;
- * <LI> Document printing;
- * <LI> The URI with which the document is associated;
- * <LI> Access to elements by their XML "ID" attributes (when the
- *	document was constructed with an appropriate XML parser);
- * <LI> Application-level control over the language in which
- *      diagnostics are provided (useful for multi-language applications
- *	such as servers);
- * <LI> Moving nodes between DOM Documents.  (DOM Level 1 only talks
- *	about nodes that are coupled to a single DOM document.)
- *
- * </UL>
- *
- *
- * @author David Brownell
- * @version $Revision$
- */
-public interface DocumentEx
-    extends Document, ElementFactory,
-	XmlReadable, XmlWritable
-{
-    /**
-     * Returns the system ID (a URI) associated with the document,
-     * or null if this is unknown.
-     */
-    public String getSystemId ();
-
-
-    /**
-     * Assigns the element factory to be used by this document.
-     */
-    public void setElementFactory (ElementFactory factory);
-
-
-    /**
-     * Returns the element factory to be used by this document.
-     */
-    public ElementFactory getElementFactory ();
-
-
-    /**
-     * Returns the element whose ID is given by the parameter; or null
-     * if no such element is known.  Element IDs are declared by
-     * attributes of type "ID", and are commonly used for internal
-     * linking by using attributes of type IDREF or IDREFS to turn
-     * XML's hierarchical data structure into a directed graph.
-     *
-     * <P> Note that DOM itself provides no way to identify which element
-     * attributes are declared with the "ID" attribute type.  This feature
-     * relies on interfaces which may not be publicly exposed, such as
-     * XML processors telling a DOM builder about those attributes.
-     *
-     * @param id The value of the ID attribute which will be matched
-     *	by any element which is returned. 
-     */
-    // Note:  HTML DOM has getElementById() with "Element" return type
-    public ElementEx getElementExById (String id);
-
-
-    /**
-     * Returns the locale to be used for diagnostic messages.
-     */
-    public Locale	getLocale ();
-
-
-    /**
-     * Assigns the locale to be used for diagnostic messages.
-     * Multi-language applications, such as web servers dealing with
-     * clients from different locales, need the ability to interact
-     * with clients in languages other than the server's default.
-     * When a Document is created, its locale is the default
-     * locale for the virtual machine.
-     *
-     * @see #chooseLocale
-     */
-    public void	setLocale (Locale locale);
-
-
-    /**
-     * Chooses a client locale to use for diagnostics, using the first
-     * language specified in the list that is supported by this DOM
-     * implementation. That locale is then automatically assigned using <a
-     * href="#setLocale(java.util.Locale)">setLocale()</a>.  Such a list
-     * could be provided by a variety of user preference mechanisms,
-     * including the HTTP <em>Accept-Language</em> header field.
-     *
-     * @see org.apache.xerces.tree.MessageCatalog
-     *
-     * @param languages Array of language specifiers, ordered with the most
-     *	preferable one at the front.  For example, "en-ca" then "fr-ca",
-     *  followed by "zh_CN".  Both RFC 1766 and Java styles are supported.
-     * @return The chosen locale, or null.
-     */
-    public Locale chooseLocale (String languages []);
-
-
-    /**
-     * Changes the "owner document" of the given node, and all child
-     * and associated attribute nodes, to be this document.  If the
-     * node has a parent, it is first removed from that parent.
-     * 
-     * @param node the node whose "owner" will be changed.
-     * @exception DOMException WRONG_DOCUMENT_ERROR when attempting
-     *	to change the owner for some other DOM implementation<P>
-     *	HIERARCHY_REQUEST_ERROR when the node is a document, document
-     *	type, entity, or notation; or when it is an attribute associated
-     *  with an element whose owner is not being (recursively) changed.
-     */
-    public void changeNodeOwner (Node node);
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/DomEx.java b/src/whiteboard/org/apache/xerces/tree/DomEx.java
deleted file mode 100644
index 26e4a13..0000000
--- a/src/whiteboard/org/apache/xerces/tree/DomEx.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import java.util.Locale;
-
-import org.w3c.dom.DOMException;
-
-
-/**
- * Concrete class for DOM exceptions, associating standard messages
- * with DOM error codes.
- *
- * @author David Brownell
- * @version $Revision$
- */
-class DomEx extends DOMException
-{
-    static String messageString (Locale locale, int code)
-    {
-	switch (code) {
-	  case INDEX_SIZE_ERR:
-	    return XmlDocument.catalog.getMessage (locale, "D-000");
-	  case DOMSTRING_SIZE_ERR:
-	    return XmlDocument.catalog.getMessage (locale, "D-001");
-	  case HIERARCHY_REQUEST_ERR:
-	    return XmlDocument.catalog.getMessage (locale, "D-002");
-	  case WRONG_DOCUMENT_ERR:
-	    return XmlDocument.catalog.getMessage (locale, "D-003");
-	  case INVALID_CHARACTER_ERR:
-	    return XmlDocument.catalog.getMessage (locale, "D-004");
-	  case NO_DATA_ALLOWED_ERR:
-	    return XmlDocument.catalog.getMessage (locale, "D-005");
-	  case NO_MODIFICATION_ALLOWED_ERR:
-	    return XmlDocument.catalog.getMessage (locale, "D-006");
-	  case NOT_FOUND_ERR:
-	    return XmlDocument.catalog.getMessage (locale, "D-007");
-	  case NOT_SUPPORTED_ERR:
-	    return XmlDocument.catalog.getMessage (locale, "D-008");
-	  case INUSE_ATTRIBUTE_ERR:
-	    return XmlDocument.catalog.getMessage (locale, "D-009");
-	  default:
-	    return XmlDocument.catalog.getMessage (locale, "D-010");
-	}
-    }
-
-    /**
-     * Creates a DOM exception which provides a standard message
-     * corresponding to the given error code, using the default
-     * locale for the message.
-     */
-    public DomEx (short code)
-    {
-	super (code, messageString (Locale.getDefault (), code));
-    }
-
-    /**
-     * Creates a DOM exception which provides a standard message
-     * corresponding to the given error code and using the specified
-     * locale for the message.
-     */
-    public DomEx (Locale locale, short code)
-    {
-	super (code, messageString (locale, code));
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/DtdEventListener.java b/src/whiteboard/org/apache/xerces/tree/DtdEventListener.java
deleted file mode 100644
index eded774..0000000
--- a/src/whiteboard/org/apache/xerces/tree/DtdEventListener.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import java.util.EventListener;
-
-import org.xml.sax.DTDHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-
-
-/**
- * When parsing XML documents, DTD related events are signaled through
- * this interface.  Examples include the beginning and end of the DTD,
- * entity declarations, and parts of the &lt;!DOCTYPE...&gt; declaration.
- * This interface supports: <UL>
- *
- * <LI> SAX 1.0 DtdHandler callbacks, which suffice to interpret element
- * attributes whose values name notations or unparsed entities. 
- *
- * <LI>DOM Level 1, which additionally requires information about parsed
- * entity declarations, as well as the ability to tell which processing
- * instructions are within the DTD.
- *
- * <LI> XML namespaces, which places requirements on names of all
- * entities and notations (they may not contain colons.)
- *
- * <LI> Recreating the <em>&lt;!DOCTYPE ...&gt;</em> declaration when
- * storing modified documents, including the unnamed external parameter
- * entity as well as the full text of the internal DTD subset.
- *
- * <LI> Layered validation of element content models and attribute
- * content restrictions, by exposing these declarations for applications
- * to record and use.
- *
- * </UL>
- *
- * <P> Events signaled through the DTDHandler interface will only
- * signaled after at <em>startDtd</em> event and before an <em>endDtd</em>
- * event.
- *
- * <P> Other than the support to recreate the DOCTYPE declaration,
- * parameter entities are not exposed.
- *
- * @see Parser
- *
- * @author David Brownell
- * @version $Revision$
- */
-public interface DtdEventListener extends DTDHandler
-{
-    /**
-     * Receive notification of the beginning of a Document Type
-     * Declaration (DTD).  The parser will invoke this method only
-     * once, before any other methods in this interface.
-     *
-     * @see #endDtd
-     *
-     * @param rootName The declared name of the root element, which
-     *	may be different from the actual name if the document is not
-     *	valid.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     */
-    public void startDtd (String rootName)
-    throws SAXException;
-
-
-    /**
-     * Reports the optional unnamed parameter entity which is processed
-     * after the internal DTD subset.  This commonly provides the entire
-     * external DTD subset, in case where the internal DTD subset does
-     * not define and use external parameter entities.  The parser will
-     * invoke this method at most once.
-     *
-     * @see #internalDtdDecl
-     *
-     * @param publicId The entity's public identifier, or null if
-     *        none was given.
-     * @param systemId The entity's system identifier.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     */
-    public void externalDtdDecl (String publicId, String systemId)
-    throws SAXException;
-
-
-    /**
-     * Reports the internal DTD subset, as unparsed markup declarations.
-     * This may also contain comments and processing instructions, if they
-     * are found in the document source.  Applications should treat this
-     * string as opaque, only using it when recreating a
-     * <em>&lt;!DOCTYPE ...&gt;</em> declaration.  The parser will invoke
-     * this method at most once.
-     *
-     * @see #externalDtdDecl
-     *
-     * @param internalSubset The document's internal subset, as unparsed
-     *	markup declarations, comments, and processing instructions.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     */
-    public void internalDtdDecl (String internalSubset)
-    throws SAXException;
-
-
-    /**
-     * Receive notification of a internal parsed entity declaration event.
-     *
-     * @see #externalEntityDecl
-     *
-     * @param name The internal entity name.
-     * @param value the value of the entity, which may include unexpanded
-     *	entity references.  Character references will have been expanded.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     */
-    public void internalEntityDecl (String name, String value)
-    throws SAXException;
-
-
-    /**
-     * Receive notification of an external parsed entity declaration event.
-     *
-     * <p>If a system identifier is present, and it is a relative URL, the
-     * parser will have resolved it fully before passing it through this
-     * method to a listener.</p>
-     *
-     * @see #unparsedEntityDecl
-     *
-     * @param name The entity name.
-     * @param publicId The entity's public identifier, or null if
-     *        none was given.
-     * @param systemId The entity's system identifier.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     */
-    public void externalEntityDecl (String name,
-		    String publicId, String systemId)
-    throws SAXException;
-
-
-    // SAX 1.0 defines unparsedEntityDecl
-
-    // SAX 1.0 defines notationDecl
-
-
-    /**
-     * Reports an element declaration found within the DTD.  The content
-     * model will be a string such as "ANY", "EMPTY", "(#PCDATA|foo)*",
-     * or "(caption?,tr*)".
-     *
-     * @param elementName The name of the element; this includes a namespace
-     *	prefix if one was used within the DTD.
-     * @param contentModel The content model as defined in the DTD, with
-     *	any whitespace removed.
-     */
-    public void elementDecl (String elementName, String contentModel)
-    throws SAXException;
-
-    /**
-     * Reports an attribute declaration found within the DTD.
-     *
-     * @param elementName The name of the element to which the attribute
-     *	applies; this includes a namespace prefix if one was used within
-     *	the DTD.
-     * @param attributeName The name of the attribute being declared; this
-     *	includes a namespace prefix if one was used within the DTD.
-     * @param attributeType The type of the attribute, either CDATA, NMTOKEN,
-     *	NMTOKENS, ENTITY, ENTITIES, NOTATION, ID, IDREF, or IDREFS as
-     *	defined in the XML specification; or null for enumerations.
-     * @param options When attributeType is null or NOTATION, this is an
-     *	array of the values which are permitted; it is otherwise null.
-     * @param defaultValue When not null, this provides the default value
-     *	of this attribute.
-     * @param isFixed When true, the defaultValue is the only legal value.
-     *	(Precludes isRequired.)
-     * @param isRequired When true, the attribute value must be provided
-     *	for each element of the named type.  (Precludes isFixed.)
-     */
-    public void attributeDecl (
-	String		elementName,
-	String		attributeName,
-	String		attributeType,
-	String		options [],
-	String		defaultValue,
-	boolean		isFixed,
-	boolean		isRequired
-    ) throws SAXException;
-
-
-    /**
-     * Receive notification of the end of a DTD.  The parser will invoke
-     * this method only once.
-     *
-     * @see #startDtd
-     *
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     */
-    public void endDtd () throws SAXException;
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/ElementEx.java b/src/whiteboard/org/apache/xerces/tree/ElementEx.java
deleted file mode 100644
index 8b41b4a..0000000
--- a/src/whiteboard/org/apache/xerces/tree/ElementEx.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Element;
-
-
-/**
- * This extends the DOM Element interface with features including XML
- * namespace support.  An ID attribute may be visible, and applications
- * may request that memory usage be reduced.
- *
- * <P> There is also support for a single strongly associated object,
- * permitting trees of XML objects to be coupled to other frameworks
- * without requiring either subclassing or external tables to manage
- * such associations.  Such techniques will be required in some cases,
- * perhaps in conjunction with this <em>userObject</em>.
- *
- * @author David Brownell
- * @version $Revision$
- */
-public interface ElementEx
-    extends Element, NodeEx, NamespaceScoped, XmlReadable
-{
-    /**
-     * Returns the value of an element attribute, as named according
-     * to the XML Namespaces draft specification.  If there is no
-     * such attribute, an empty string is returned.
-     *
-     * @param uri The namespace for the name; may be null to indicate
-     *	the document's default namespace.
-     * @param name The "local part" of the name, without a colon.
-     * @return the attribute value, or an empty string
-     */
-    public String getAttribute (String uri, String name);
-
-    /**
-     * Returns the value of an element attribute, as named according
-     * to the XML Namespaces draft specification.  If there is no
-     * such attribute, null is returned.
-     *
-     * @param uri The namespace for the name; may be null to indicate
-     *	the document's default namespace.
-     * @param name The "local part" of the name, without a colon.
-     * @return the attribute node, or null
-     */
-    public Attr getAttributeNode (String uri, String name);
-
-    /**
-     * Returns the name of the attribute declared to hold the element's ID,
-     * or null if no such declaration is known.  This is normally declared
-     * in the Document Type Declaration (DTD).  Parsers are not required to
-     * parse DTDs, and document trees constructed without a parser may not
-     * have access to the DTD, so such declarations may often not be known.
-     *
-     * <P> ID attributes are used within XML documents to support links
-     * using IDREF and IDREFS attributes.  They are also used in current
-     * drafts of XPointer and XSL specifications.
-     *
-     * @return the name of the ID attribute
-     */
-    public String	getIdAttributeName ();
-
-    /**
-     * Returns the object associated with this element.  In cases where
-     * more than one such object must be so associated, the association
-     * must be maintained externally.
-     */
-    public Object	getUserObject ();
-
-    /**
-     * Assigns an object to be associated with this element.
-     */
-    public void		setUserObject (Object obj);
-
-    /**
-     * Requests that the element minimize the amount of space it uses,
-     * to conserve memory.  Children are not affected.
-     */
-    public void		trimToSize ();
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/ElementFactory.java b/src/whiteboard/org/apache/xerces/tree/ElementFactory.java
deleted file mode 100644
index 3348248..0000000
--- a/src/whiteboard/org/apache/xerces/tree/ElementFactory.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import org.w3c.dom.Element;
-
-
-/**
- * This interface defines a factory which can be used by documents
- * to provide namespace-aware element creation.
- *
- * <P> A variety of implementation techniques are possible for this
- * interface.  Among them are compiled-in mappings between element
- * names and classes, mappings defined in configuration files, ones
- * derived from the document as it is parsed, and using namespaces
- * to identify packages to be used with classes whose names correspond
- * to elements.
- *
- * <P> DOM implementations will have constraints on the implementation
- * classes returned by this factory, typically that they be subclasses
- * of their implementation base class.
- *
- * @see DocumentEx
- *
- * @author David Brownell
- * @version $Revision$
- */
-public interface ElementFactory
-{
-    /**
-     * This is like the DOM <em>Document.createElement</em> method,
-     * except that its return type is different.
-     */
-    public ElementEx createElementEx (String tag);
-
-    /**
-     * Returns an element which may be specialized to support application
-     * specific behaviors as associated with the specified namespace.
-     */
-    public ElementEx createElementEx (String uri, String tag);
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/ElementNode.java b/src/whiteboard/org/apache/xerces/tree/ElementNode.java
deleted file mode 100644
index f80c9ff..0000000
--- a/src/whiteboard/org/apache/xerces/tree/ElementNode.java
+++ /dev/null
@@ -1,639 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import java.io.CharArrayWriter;
-import java.io.IOException;
-import java.io.Writer;
-
-import java.util.Enumeration;
-
-import org.apache.xerces.tree.XmlNames;
-
-import org.w3c.dom.*;
-
-
-/**
- * This class represents XML elements in a parse tree, and is often
- * subclassed to add custom behaviors.  When an XML Document object
- * is built using an <em>XmlDocumentBuilder</em> instance, simple
- * declarative configuration information may be used to control whether
- * this class, or some specialized subclass (e.g. supporting HTML DOM
- * methods) is used for elements in the resulting tree.
- *
- * <P> As well as defining new methods to provide behaviors which are
- * specific to application frameworks, such as Servlets or Swing, such
- * subclasses may also override methods such as <em>doneParse</em>
- * and <em>appendChild</em> to perform some kinds of processing during
- * tree construction.  Such processing can include transforming tree
- * structure to better suit the needs of a given application.  When
- * such transformation is done, the <em>XmlWritable</em> methods
- * may need to be overridden to make elements transform themselves back
- * to XML without losing information.  (One common transformation is
- * eliminating redundant representations of data; attributes of an XML
- * element may correspond to defaultable object properties, and so on.)
- *
- * <P> Element nodes also support a single <em>userObject</em> property,
- * which may be used to bind objects to elements where subclassing is
- * either not possible or is inappropriate.  For example, user interface
- * objects often derive from <code>java.awt.Component</code>, so that
- * they can't extend a different class (<em>ElementNode</em>).
- *
- * @see XmlDocumentBuilder
- *
- * @author David Brownell
- * @version $Revision$
- */
-public class ElementNode extends NamespacedNode implements ElementEx
-{
-    private AttributeSet	attributes;
-    private String		idAttributeName;
-    private Object		userObject;
-
-    private static final char	tagStart [] = { '<', '/' };
-    private static final char	tagEnd [] = { ' ', '/', '>' };
-    private static final String
-        DEFAULT_XML_NS_URI = "http://www.w3.org/XML/1998/namespace";
-    
-    /**
-     * Partially constructs an element; its tag will be assigned
-     * by the factory (or subclass), while attributes and the
-     * parent (and implicitly, siblings) will assigned when it is
-     * joined to a DOM document.
-     */
-    public ElementNode () { }
-
-    public ElementNode(String namespaceURI, String qualifiedName)
-        throws DomEx
-    {
-        // Check arguments and throw appropriate exceptions
-        checkArguments(namespaceURI, qualifiedName);
-
-        name = qualifiedName;
-        this.namespaceURI = namespaceURI;
-    }
-
-    private void checkArguments(String namespaceURI, String qualifiedName)
-        throws DomEx
-    {
-        // [6] QName ::= (Prefix ':')? LocalPart
-        // [7] Prefix ::= NCName
-        // [8] LocalPart ::= NCName
-
-	if (qualifiedName == null) {
-            throw new DomEx(DomEx.NAMESPACE_ERR);
-        }
-
-	int first = qualifiedName.indexOf(':');
-
-        if (first <= 0) {
-            // no Prefix, only check LocalPart
-            if (!XmlNames.isUnqualifiedName(qualifiedName)) {
-                throw new DomEx(DomEx.INVALID_CHARACTER_ERR);
-            }
-            return;
-        }
-
-        // Prefix exists, check everything
-
-	int last = qualifiedName.lastIndexOf(':');
-	if (last != first) {
-            throw new DomEx(DomEx.NAMESPACE_ERR);
-        }
-	
-        String prefix = qualifiedName.substring(0, first);
-        String localName = qualifiedName.substring(first + 1);
-	if (!XmlNames.isUnqualifiedName(prefix)
-                || !XmlNames.isUnqualifiedName(localName)) {
-            throw new DomEx(DomEx.INVALID_CHARACTER_ERR);
-        }
-
-        // If we get here then we must have a valid prefix
-        if (namespaceURI == null || namespaceURI.equals("")
-                || (prefix.equals("xml") &&
-                    !namespaceURI.equals(DEFAULT_XML_NS_URI))) {
-            throw new DomEx(DomEx.NAMESPACE_ERR);
-        }
-    }
-
-    public void trimToSize ()
-    {
-	super.trimToSize ();
-	if (attributes != null)
-	    attributes.trimToSize ();
-    }
-
-    /**
-     * Assigns the element's name, when the element has been
-     * constructed using the default constructor.  For use by
-     * element factories potentially by custom subclasses. 
-     */
-    protected void setTag (String t) { name = t; }
-
-    // Assigns the element's attributes.
-    void setAttributes (AttributeSet a)
-    {
-	AttributeSet oldAtts = attributes;
-
-	// Check if the current AttributeSet or any attribute is readonly
-	// isReadonly checks if any of the attributes in the AttributeSet
-	// is readonly..
-	if (oldAtts != null && oldAtts.isReadonly ())
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-
-	if (a != null)
-	    a.setNameScope (this);
-	attributes = a;
-	if (oldAtts != null)
-	    oldAtts.setNameScope (null);
-    }
-
-    // package private -- overrides base class method
-    void checkChildType (int type)
-    throws DOMException
-    {
-	switch (type) {
-	  case ELEMENT_NODE:
-	  case TEXT_NODE:
-	  case COMMENT_NODE:
-	  case PROCESSING_INSTRUCTION_NODE:
-	  case CDATA_SECTION_NODE:
-	  case ENTITY_REFERENCE_NODE:
-	    return;
-	  default:
-	    throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	}
-    }
-
-    // package private -- overrides base class method
-    public void setReadonly (boolean deep)
-    {
-	if (attributes != null)
-	    attributes.setReadonly ();
-	super.setReadonly (deep);
-    }
-
-    public String getNamespace ()
-    {
-	String	prefix;
-	String	value;
-
-	if ((prefix = getPrefix ()) == null)
-	    return getInheritedAttribute ("xmlns");
-
-	//
-	// XXX return real URLs for these, both here and
-	// in AttributeNode ...
-	//
-	if ("xml".equals (prefix) || "xmlns".equals (prefix))
-	    return null;
-
-	value = getInheritedAttribute ("xmlns:" + prefix);
-	if (value == null)
-	    throw new IllegalStateException (getMessage ("EN-000",
-					     new Object [] { prefix }));
-
-	return value;
-    }
-
-    /** <b>DOM:</b> Returns the attributes of this element. */
-    public NamedNodeMap getAttributes ()
-    {
-	if (attributes == null)
-	    attributes = new AttributeSet (this);
-        return attributes;
-    }
-        
-    /**
-     * Returns the element and its content as a string, which includes
-     * all the markup embedded in this element.  If the element is not
-     * fully constructed, the content will not be an XML tag.
-     */
-    public String toString ()
-    {
-	try {
-	    CharArrayWriter	out = new CharArrayWriter ();
-	    XmlWriteContext	x = new XmlWriteContext (out);
-	    writeXml (x);
-	    return out.toString ();
-	} catch (Exception e) {
-	    return super.toString ();
-	}
-    }
-    
-    
-    /**
-     * Writes this element and all of its children out, as well
-     * formed XML.
-     */
-    public void writeXml (XmlWriteContext context) throws IOException
-    {
-	Writer	out = context.getWriter ();
-
-	if (name == null)
-	   throw new IllegalStateException ( getMessage ("EN-002"));
-	   
-	out.write (tagStart, 0, 1);	// "<"
-	out.write (name);
-	
-        if (attributes != null)
-	    attributes.writeXml (context);
-
-	//
-	// Write empty nodes as "<EMPTY />" to make sure version 3
-	// and 4 web browsers can read empty tag output as HTML.
-	// XML allows "<EMPTY/>" too, of course.
-	//
-	if (!hasChildNodes ())
-	    out.write (tagEnd, 0, 3);	// " />"
-	else  {
-	    out.write (tagEnd, 2, 1);	// ">"
-	    writeChildrenXml (context);
-	    out.write (tagStart, 0, 2);	// "</"
-	    out.write (name);
-	    out.write (tagEnd, 2, 1);	// ">"
-	}
-    }
-
-    /**
-     * Assigns the name of the element's ID attribute; only one attribute
-     * may have the ID type.  XML supports a kind of validatable internal
-     * linking using ID attributes, with IDREF attributes identifying
-     * specific nodes (and IDREFS attributes identifying sets of them).
-     */
-    public void setIdAttributeName (String attName)
-    {
-	if (readonly)
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-	idAttributeName = attName;
-    }
-
-    /**
-     * Returns the name of the element's ID attribute, if one is known.
-     */
-    public String getIdAttributeName ()
-	{ return idAttributeName; }
-
-    
-    public void setUserObject (Object userObject)
-	{ this.userObject = userObject; }
-
-    public Object getUserObject ()
-	{ return userObject; }
-
-    // DOM support
-
-    /** <b>DOM:</b> Returns the ELEMENT_NODE node type. */
-    public short getNodeType ()  { return ELEMENT_NODE; }
-
-    /** <b>DOM:</b> Returns the name of the XML tag for this element. */
-    public String getTagName () { return name; }
-    
-    /** <b>DOM:</b> Returns the name of the XML tag for this element. */
-    public String getNodeName () { return name; }
-
-    /** <b>DOM:</b> Returns the value of the named attribute, or an empty
-     * string 
-     */
-    public String getAttribute (String name)
-    {
-	return (attributes == null)
-	    ? ""
-	    : attributes.getValue (name);
-    }
-
-    /**
-     * <b>DOM2:</b>
-     * @since DOM Level 2
-     */
-    public String getAttributeNS(String namespaceURI, String localName) {
-        //XXX fix this
-	if (attributes == null) {
-	    return "";
-        }
-	Attr attr = getAttributeNodeNS(namespaceURI, localName);
-	if (attr == null) {
-	    return "";
-        }
-	return attr.getValue();
-    }
-
-    /** <b>DOM2:</b> Returns the value of the named attribute, or an empty
-     * string 
-     */
-    public boolean hasAttribute (String name)
-    {
-        if (attributes == null) {
-	    return false;	
-	} else if (attributes.getValue (name) != null) {
-	    return true;
-	}
-	return false;
-    }
-
-    /**
-     * <b>DOM2:</b>
-     * @since DOM Level 2
-     */
-    public boolean hasAttributeNS(String namespaceURI, String localName) {
-	if (attributes == null) {
-	    return false;
-        }
-	Attr attr = getAttributeNodeNS(namespaceURI, localName);
-	if (attr == null) {
-	    return false;
-        }
-	return true;
-    }
-
-    public String getAttribute (String uri, String name)
-    {
-	Attr	attr;
-
-	if (attributes == null)
-	    return "";
-	attr = getAttributeNode (uri, name);
-	if (attr == null)
-	    return "";
-	return attr.getValue ();
-    }
-
-    /**
-     * <b>DOM2:</b>
-     * @since DOM Level 2
-     */
-    public Attr getAttributeNodeNS(String namespaceURI, String localName) {
-	if (localName == null) {
-	    return null;
-        }
-	if (attributes == null) {
-            return null;
-        }
-        for (int i = 0; ; i++) {
-            AttributeNode attr = (AttributeNode) attributes.item(i);
-            if (attr == null) {
-                return null;
-            }
-            if (attr.getLocalName().equals(localName)
-                && attr.getNamespaceURI().equals(namespaceURI)) {
-                return attr;
-            }
-        }
-    }
-
-    public Attr getAttributeNode (String uri, String name)
-    {
-	if (name == null)
-	    return null;
-	if (attributes != null) {
-	    for (int i = 0; ; i++) {
-		AttributeNode	attr;
-		String		ns;
-
-		attr = (AttributeNode) attributes.item (i);
-		if (attr == null)
-		    return null;
-		if (!name.equals (attr.getName ()))
-		    continue;
-		ns = attr.getNamespace ();
-		if (ns != null && ns.equals (uri))
-		    return attr;
-	    }
-	}
-	return null;
-    }
-
-    
-    /**
-     * <b>DOM:</b> Assigns or modifies the value of the specified attribute.
-     */
-    public void setAttribute (String name, String value)
-    throws DOMException
-    {
-	AttributeNode	att;
-
-	if (readonly)
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-	if (attributes == null)
-	    attributes = new AttributeSet (this);
-	if ((att = (AttributeNode) attributes.getNamedItem (name)) != null)
-	    att.setNodeValue (value);
-	else {
-	    att = new AttributeNode (name, value, true, null);
-	    att.setOwnerDocument ((XmlDocument) getOwnerDocument ());
-	    att.setOwnerElement(this);
-	    attributes.setNamedItem (att);
-	}
-    }
-    
-    /**
-     * <b>DOM2:</b>
-     * @since DOM Level 2
-     * XXX Fix err handling and default DEFAULT_XML_NS_URI
-     */
-    public void setAttributeNS(String namespaceURI, String qualifiedName, 
-                               String value)
-        throws DOMException
-    {
-        String prefix = XmlNames.getPrefix(qualifiedName);
-        if (prefix == null) {
-            throw new DomEx(DomEx.NAMESPACE_ERR);
-        }
-
-        Attr attr = getAttributeNodeNS(namespaceURI,
-                XmlNames.getLocalPart(qualifiedName));
-        if (attr == null) {
-            attr = new AttributeNode(namespaceURI, qualifiedName, value,
-                                     true, null);
-            setAttributeNodeNS(attr);
-        } else {
-            attr.setValue(value);
-            attr.setPrefix(prefix);
-        }
-    }
-
-    /**
-     * <b>DOM2:</b>
-     * @since DOM Level 2
-     */
-    public Attr setAttributeNodeNS(Attr newAttr) throws DOMException {
-	if (readonly) {
-	    throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
-        }
-        if (newAttr.getOwnerDocument() != getOwnerDocument()) {
-	    throw new DomEx(DomEx.WRONG_DOCUMENT_ERR);
-        }
-        Element ownerElement = newAttr.getOwnerElement();
-        if (ownerElement != null || ownerElement != this) {
-	    throw new DomEx(DomEx.INUSE_ATTRIBUTE_ERR);
-        }
-
-	if (attributes == null) {
-	    attributes = new AttributeSet(this);
-        }
-
-        // Safe to assume we are being passed an AttributeNode
-        ((AttributeNode)newAttr).setOwnerElement(this);
-
-	return (Attr)attributes.setNamedItem(newAttr);
-    }
-
-    /** <b>DOM:</b> Remove the named attribute. */
-    public void removeAttribute (String name)
-    throws DOMException
-    {
-	if (readonly)
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-	if (attributes == null)
-	    throw new DomEx (DomEx.NOT_FOUND_ERR);
-        attributes.removeNamedItem (name);
-    }
-
-    /**
-     * <b>DOM2:</b>
-     * @since DOM Level 2
-     */
-    public void removeAttributeNS(String namespaceURI, String localName)
-        throws DOMException
-    {
-	if (readonly) {
-	    throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
-        }
-        attributes.removeNamedItemNS(namespaceURI, localName);
-    }
-
-    /** <b>DOM:</b>  returns the attribute */
-    public Attr getAttributeNode (String name)
-    {
-	if (attributes != null)
-	    return (Attr) attributes.getNamedItem (name);
-	else
-	    return null;
-    }
-    
-    /** <b>DOM:</b> assigns the attribute */
-    public Attr setAttributeNode (Attr newAttr)
-    throws DOMException
-    {
-	if (readonly)
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-	if (!(newAttr instanceof AttributeNode))
-	    throw new DomEx (DomEx.WRONG_DOCUMENT_ERR);
-
-	if (attributes == null) 
-	    attributes = new AttributeSet (this);
-
-        ((AttributeNode)newAttr).setOwnerElement(this);
-	return (Attr) attributes.setNamedItem(newAttr);
-    }
-    
-    /** <b>DOM:</b> removes the attribute with the same name as this one */
-    public Attr removeAttributeNode (Attr oldAttr)
-    throws DOMException
-    {
-	if (isReadonly ())
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-
-	Attr	attr = getAttributeNode (oldAttr.getNodeName ());
-	if (attr == null)
-	    throw new DomEx (DomEx.NOT_FOUND_ERR);
-	removeAttribute (attr.getNodeName ());
-	return attr;
-    }
-
-    
-    /**
-     * Creates a new unparented node whose attributes are the same as
-     * this node's attributes; if <em>deep</em> is true, the children
-     * of this node are cloned as children of the new node.
-     */
-    public Node cloneNode (boolean deep)
-    {
-	try {
-	    ElementNode	retval;
-
-	    retval = (ElementNode) getOwnerDocument().createElement (name);
-	    if (attributes != null)
-		retval.setAttributes (new AttributeSet (attributes, true));
-	    if (deep) {
-		for (int i = 0; true; i++) {
-		    Node	node = item (i);
-		    if (node == null)
-			break;
-		    retval.appendChild (node.cloneNode (true));
-		}
-	    }
-	    return retval;
-	} catch (DOMException e) {
-	    throw new RuntimeException (getMessage ("EN-001"));
-	}
-    }
-
-    /**
-     * Convenience method to construct a non-prettyprinting XML write
-     * context and call writeXml with it.  Subclasses may choose to
-     * to override this method to generate non-XML text, 
-     *
-     * @param out where to emit the XML content of this node
-     */
-    public void write (Writer out) throws IOException
-    {
-	writeXml (new XmlWriteContext (out));
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/MessageCatalog.java b/src/whiteboard/org/apache/xerces/tree/MessageCatalog.java
deleted file mode 100644
index 8ae29c2..0000000
--- a/src/whiteboard/org/apache/xerces/tree/MessageCatalog.java
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * $Id$ 
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import java.io.InputStream;
-import java.text.FieldPosition;
-import java.text.MessageFormat;
-import java.util.Hashtable;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-
-/**
- * This class provides support for multi-language string lookup, as needed
- * to localize messages from applications supporting multiple languages
- * at the same time.  One class of such applications is network services,
- * such as HTTP servers, which talk to clients who may not be from the
- * same locale as the server.  This class supports a form of negotiation
- * for the language used in presenting a message from some package, where
- * both user (client) preferences and application (server) support are
- * accounted for when choosing locales and formatting messages.
- *
- * <P> Each package should have a singleton package-private message catalog
- * class.  This ensures that the correct class loader will always be used to
- * access message resources, and minimizes use of memory: <PRE>
- *    package <em>some.package</em>;
- *    
- *    // "foo" might be public
- *    class foo {
- *	  ...
- *        // package private
- *        static final Catalog messages = new Catalog ();
- *        static final class Catalog extends MessageCatalog {
- *            Catalog () { super (Catalog.class); }
- *	  }
- *	  ...
- *    }
- * </PRE>
- *
- * <P> Messages for a known client could be generated using code
- * something like this:  <PRE>
- *    String clientLanguages [];
- *    Locale clientLocale;
- *    String clientMessage;
- *
- *    // client languages will probably be provided by client,
- *    // e.g. by an HTTP/1.1 "Accept-Language" header.
- *    clientLanguages = new String [] { "en-ca", "fr-ca", "ja", "zh" };
- *    clientLocale = foo.messages.chooseLocale (clientLanguages);
- *    clientMessage = foo.messages.getMessage (clientLocale,
- *        "fileCount",
- *	  new Object [] { new Integer (numberOfFiles) }
- *        );
- * </PRE>
- *
- * <P> At this time, this class does not include functionality permitting
- * messages to be passed around and localized after-the-fact.  The consequence
- * of this is that the locale for messages must be passed down through layers
- * which have no normal reason to support such passdown, or else the system
- * default locale must be used instead of the one the client needs.
- *
- * <P> <hr> The following guidelines should be used when constructiong
- * multi-language applications:  <OL>
- *
- *	<LI> Always use <a href=#chooseLocale>chooseLocale</a> to select the
- *	locale you pass to your <code>getMessage</code> call.  This lets your
- *	applications use IETF standard locale names, and avoids needless
- *	use of system defaults.
- *
- *	<LI> The localized messages for a given package should always go in
- *	a separate <em>resources</em> sub-package.  There are security
- *	implications; see below.
- *
- *	<LI> Make sure that a language name is included in each bundle name,
- *	so that the developer's locale will not be inadvertently used. That
- *	is, don't create defaults like <em>resources/Messages.properties</em>
- *	or <em>resources/Messages.class</em>, since ResourceBundle will choose
- *	such defaults rather than giving software a chance to choose a more
- *	appropriate language for its messages.  Your message bundles should
- *	have names like <em>Messages_en.properties</em> (for the "en", or
- *	English, language) or <em>Messages_ja.class</em> ("ja" indicates the
- *	Japanese language).
- *
- *	<LI> Only use property files for messages in languages which can
- *	be limited to the ISO Latin/1 (8859-1) characters supported by the
- *	property file format.  (This is mostly Western European languages.)
- *	Otherwise, subclass ResourceBundle to provide your messages; it is
- *	simplest to subclass <code>java.util.ListResourceBundle</code>.
- *
- *	<LI> Never use another package's message catalog or resource bundles.
- *	It should not be possible for a change internal to one package (such
- *	as eliminating or improving messages) to break another package.
- *
- *	</OL>
- *	
- * <P> The "resources" sub-package can be treated separately from the
- * package with which it is associated.  That main package may be sealed
- * and possibly signed, preventing other software from adding classes to
- * the package which would be able to access methods and data which are
- * not designed to be publicly accessible.  On the other hand, resources
- * such as localized messages are often provided after initial product
- * shipment, without a full release cycle for the product.  Such files
- * (text and class files) need to be added to some package.  Since they
- * should not be added to the main package, the "resources" subpackage is
- * used without risking the security or integrity of that main package
- * as distributed in its JAR file.
- *
- * @see java.util.Locale
- * @see java.util.ListResourceBundle
- * @see java.text.MessageFormat
- *
- * @version 1.10
- * @author David Brownell
- */
-// leave this as "abstract" -- each package needs its own subclass,
-// else it's not always going to be using the right class loader.
-abstract public class MessageCatalog {
-    private String			bundleName;
-
-    /**
-     * Create a message catalog for use by classes in the same package
-     * as the specified class.  This uses <em>Messages</em> resource
-     * bundles in the <em>resources</em> sub-package of class passed as
-     * a parameter. 
-     *
-     * @param packageMember Class whose package has localized messages
-     */
-    protected MessageCatalog (Class packageMember)
-    {
-	this (packageMember, "Messages");
-    }
-
-    /**
-     * Create a message catalog for use by classes in the same package
-     * as the specified class.  This uses the specified resource
-     * bundle name in the <em>resources</em> sub-package of class passed
-     * as a parameter; for example, <em>resources.Messages</em>.
-     *
-     * @param packageMember Class whose package has localized messages
-     * @param bundle Name of a group of resource bundles
-     */
-    private MessageCatalog (Class packageMember, String bundle)
-    {
-	int	index;
-
-	bundleName = packageMember.getName ();
-	index = bundleName.lastIndexOf ('.');
-	if (index == -1)	// "ClassName"
-	    bundleName = "";
-	else			// "some.package.ClassName"
-	    bundleName = bundleName.substring (0, index) + ".";
-	bundleName = bundleName + "resources." + bundle;
-    }
-
-
-    /**
-     * Get a message localized to the specified locale, using the message ID
-     * and package name if no message is available.  The locale is normally
-     * that of the client of a service, chosen with knowledge that both the
-     * client and this server support that locale.  There are two error
-     * cases:  first, when the specified locale is unsupported or null, the
-     * default locale is used if possible; second, when no bundle supports
-     * that locale, the message ID and package name are used.
-     *
-     * @param locale The locale of the message to use.  If this is null,
-     *	the default locale will be used.
-     * @param messageId The ID of the message to use.
-     * @return The message, localized as described above.
-     */
-    public String getMessage (
-	Locale		locale,
-	String		messageId
-    ) {
-	ResourceBundle	bundle;
-
-	// cope with unsupported locale...
-	if (locale == null)
-	    locale = Locale.getDefault ();
-
-	try {
-	    bundle = ResourceBundle.getBundle (bundleName, locale);
-	    return bundle.getString (messageId);
-	} catch (MissingResourceException e) {
-	    return packagePrefix (messageId);
-	} 
-    }
-
-    private String packagePrefix (String messageId)
-    {
-	String	temp = getClass ().getName ();
-	int	index = temp.lastIndexOf ('.');
-
-	if (index == -1)	// "ClassName"
-	    temp = "";
-	else			// "some.package.ClassName"
-	    temp = temp.substring (0, index);
-	return temp + '/' + messageId;
-    }
-
-
-    /**
-     * Format a message localized to the specified locale, using the message
-     * ID with its package name if none is available.  The locale is normally
-     * the client of a service, chosen with knowledge that both the client
-     * server support that locale.  There are two error cases:  first, if the
-     * specified locale is unsupported or null, the default locale is used if
-     * possible; second, when no bundle supports that locale, the message ID
-     * and package name are used.
-     *
-     * @see java.text.MessageFormat
-     *
-     * @param locale The locale of the message to use.  If this is null,
-     *	the default locale will be used.
-     * @param messageId The ID of the message format to use.
-     * @param parameters Used when formatting the message.  Objects in
-     *	this list are turned to strings if they are not Strings, Numbers,
-     *	or Dates (that is, if MessageFormat would treat them as errors).
-     * @return The message, localized as described above.
-     */
-    public String getMessage (
-	Locale		locale,
-	String		messageId,
-	Object		parameters []
-    ) {
-	if (parameters == null)
-	    return getMessage (locale, messageId);
-
-	// since most messages won't be tested (sigh), be friendly to
-	// the inevitable developer errors of passing random data types
-	// to the message formatting code.
-	for (int i = 0; i < parameters.length; i++) {
-	    if  (!(parameters[i] instanceof String)
-		    && !(parameters[i] instanceof Number)
-		    && !(parameters[i] instanceof java.util.Date)) {
-		if (parameters [i] == null)
-		    parameters [i] = "(null)";
-		else
-		    parameters[i] = parameters[i].toString();
-	    }
-	}
-
-	// similarly, cope with unsupported locale...
-	if (locale == null)
-	    locale = Locale.getDefault ();
-
-	// get the appropriately localized MessageFormat object
-	ResourceBundle	bundle;
-	MessageFormat	format;
-
-	try {
-	    bundle = ResourceBundle.getBundle (bundleName, locale);
-	    format = new MessageFormat (bundle.getString (messageId));
-	} catch (MissingResourceException e) {
-	    String retval;
-
-	    retval = packagePrefix (messageId);
-	    for (int i = 0; i < parameters.length; i++) {
-		retval += ' ';
-		retval += parameters [i];
-	    }
-	    return retval;
-	} 
-	format.setLocale (locale);
-
-	// return the formatted message
-	StringBuffer	result = new StringBuffer ();
-
-	result = format.format (parameters, result, new FieldPosition (0));
-	return result.toString ();
-    }
-
-
-    /**
-     * Chooses a client locale to use, using the first language specified in
-     * the list that is supported by this catalog.  If none of the specified
-     * languages is supported, a null value is returned.  Such a list of
-     * languages might be provided in an HTTP/1.1 "Accept-Language" header
-     * field, or through some other content negotiation mechanism.
-     *
-     * <P> The language specifiers recognized are RFC 1766 style ("fr" for
-     * all French, "fr-ca" for Canadian French), although only the strict
-     * ISO subset (two letter language and country specifiers) is currently
-     * supported.  Java-style locale strings ("fr_CA") are also supported.
-     *
-     * @see java.util.Locale
-     *
-     * @param languages Array of language specifiers, ordered with the most
-     *	preferable one at the front.  For example, "en-ca" then "fr-ca",
-     *  followed by "zh_CN".
-     * @return The most preferable supported locale, or null.
-     */
-    public Locale chooseLocale (String languages [])
-    {
-	if ((languages = canonicalize (languages)) != null) {
-	    for (int i = 0; i < languages.length; i++)
-		if (isLocaleSupported (languages [i]))
-		    return getLocale (languages [i]);
-	}
-	return null;
-    }
-
-
-    //
-    // Canonicalizes the RFC 1766 style language strings ("en-in") to
-    // match standard Java usage ("en_IN"), removing strings that don't
-    // use two character ISO language and country codes.   Avoids all
-    // memory allocations possible, so that if the strings passed in are
-    // just lowercase ISO codes (a common case) the input is returned.
-    //
-    private String [] canonicalize (String languages [])
-    {
-	boolean		didClone = false;
-	int		trimCount = 0;
-
-	if (languages == null)
-	    return languages;
-
-	for (int i = 0; i < languages.length; i++) {
-	    String	lang = languages [i];
-	    int		len = lang.length ();
-
-	    // no RFC1766 extensions allowed; "zh" and "zh-tw" (etc) are OK
-	    // as are regular locale names with no variant ("de_CH").
-	    if (!(len == 2 || len == 5)) {
-		if (!didClone) {
-		    languages = (String []) languages.clone ();
-		    didClone = true;
-		}
-		languages [i] = null;
-		trimCount++;
-		continue;
-	    }
-
-	    // language code ... if already lowercase, we change nothing
-	    if (len == 2) {
-		lang = lang.toLowerCase ();
-		if (lang != languages [i]) {
-		    if (!didClone) {
-			languages = (String []) languages.clone ();
-			didClone = true;
-		    }
-		    languages [i] = lang;
-		}
-		continue;
-	    }
-
-	    // language_country ... fixup case, force "_"
-	    char	buf [] = new char [5];
-
-	    buf [0] = Character.toLowerCase (lang.charAt (0));
-	    buf [1] = Character.toLowerCase (lang.charAt (1));
-	    buf [2] = '_';
-	    buf [3] = Character.toUpperCase (lang.charAt (3));
-	    buf [4] = Character.toUpperCase (lang.charAt (4));
-	    if (!didClone) {
-		languages = (String []) languages.clone ();
-		didClone = true;
-	    }
-	    languages [i] = new String (buf);
-	}
-
-	// purge any shadows of deleted RFC1766 extended language codes
-	if (trimCount != 0) {
-	    String	temp [] = new String [languages.length - trimCount];
-	    int		i;
-
-	    for (i = 0, trimCount = 0; i < temp.length; i++) {
-		while (languages [i + trimCount] == null)
-		    trimCount++;
-		temp [i] = languages [i + trimCount];
-	    }
-	    languages = temp;
-	}
-	return languages;
-    }
-
-
-    //
-    // Returns a locale object supporting the specified locale, using
-    // a small cache to speed up some common languages and reduce the
-    // needless allocation of memory.
-    //
-    private Locale getLocale (String localeName)
-    {
-	String		language, country;
-	int		index;
-
-	index = localeName.indexOf ('_');
-	if (index == -1) {
-	    //
-	    // Special case the builtin JDK languages
-	    //
-	    if (localeName.equals ("de"))
-		return Locale.GERMAN;
-	    if (localeName.equals ("en"))
-		return Locale.ENGLISH;
-	    if (localeName.equals ("fr"))
-		return Locale.FRENCH;
-	    if (localeName.equals ("it"))
-		return Locale.ITALIAN;
-	    if (localeName.equals ("ja"))
-		return Locale.JAPANESE;
-	    if (localeName.equals ("ko"))
-		return Locale.KOREAN;
-	    if (localeName.equals ("zh"))
-		return Locale.CHINESE;
-
-	    language = localeName;
-	    country = "";
-	} else {
-	    if (localeName.equals ("zh_CN"))
-		return Locale.SIMPLIFIED_CHINESE;
-	    if (localeName.equals ("zh_TW"))
-		return Locale.TRADITIONAL_CHINESE;
-
-	    //
-	    // JDK also has constants for countries:  en_GB, en_US, en_CA,
-	    // fr_FR, fr_CA, de_DE, ja_JP, ko_KR.  We don't use those.
-	    //
-	    language = localeName.substring (0, index);
-	    country = localeName.substring (index + 1);
-	}
-
-	return new Locale (language, country);
-    }
-
-
-    //
-    // cache for isLanguageSupported(), below ... key is a language
-    // or locale name, value is a Boolean
-    //
-    private Hashtable		cache = new Hashtable (5);
-
-
-    /**
-     * Returns true iff the specified locale has explicit language support.
-     * For example, the traditional Chinese locale "zh_TW" has such support
-     * if there are message bundles suffixed with either "zh_TW" or "zh".
-     *
-     * <P> This method is used to bypass part of the search path mechanism
-     * of the <code>ResourceBundle</code> class, specifically the parts which
-     * force use of default locales and bundles.  Such bypassing is required
-     * in order to enable use of a client's preferred languages.  Following
-     * the above example, if a client prefers "zh_TW" but can also accept
-     * "ja", this method would be used to detect that there are no "zh_TW"
-     * resource bundles and hence that "ja" messages should be used.  This
-     * bypasses the ResourceBundle mechanism which will return messages in
-     * some other locale (picking some hard-to-anticipate default) instead
-     * of reporting an error and letting the client choose another locale.
-     *
-     * @see java.util.Locale
-     *
-     * @param localeName A standard Java locale name, using two character
-     *	language codes optionally suffixed by country codes.
-     * @return True iff the language of that locale is supported.
-     */
-    public boolean isLocaleSupported (String localeName)
-    {
-	//
-	// Use previous results if possible.  We expect that the codebase
-	// is immutable, so we never worry about changing the cache.
-	// 
-	Boolean		value = (Boolean) cache.get (localeName);
-
-	if (value != null)
-	    return value.booleanValue ();
-
-	//
-	// Try "language_country_variant", then "language_country",
-	// then finally "language" ... assuming the longest locale name
-	// is passed.  If not, we'll try fewer options.
-	//
-	ClassLoader		loader = null;
-
-	for (;;) {
-	    String		name = bundleName + "_" + localeName;
-
-	    // look up classes ...
-	    try {
-		Class.forName (name);
-		cache.put (localeName, Boolean.TRUE);
-		return true;
-	    } catch (Exception e) {}
-
-	    // ... then property files (only for ISO Latin/1 messages)
-	    InputStream		in;
-
-	    if (loader == null)
-		loader = getClass ().getClassLoader ();
-
-	    name = name.replace ('.', '/');
-	    name = name + ".properties";
-	    if (loader == null)
-		in = ClassLoader.getSystemResourceAsStream (name);
-	    else
-		in = loader.getResourceAsStream (name);
-	    if (in != null) {
-		cache.put (localeName, Boolean.TRUE);
-		return true;
-	    }
-
-	    int index = localeName.indexOf ('_');
-
-	    if (index > 0)
-		localeName = localeName.substring (0, index);
-	    else
-		break;
-	}
-
-	//
-	// If we got this far, we failed.  Remember for later.
-	//
-	cache.put (localeName, Boolean.FALSE);
-	return false;
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/NamespaceScoped.java b/src/whiteboard/org/apache/xerces/tree/NamespaceScoped.java
deleted file mode 100644
index 13784e6..0000000
--- a/src/whiteboard/org/apache/xerces/tree/NamespaceScoped.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import org.w3c.dom.Node;
-
-
-/**
- * This interface is supported by elements and attributes whose names
- * are scoped according to the XML Namespaces specification.
- *
- * @author David Brownell
- * @version $Revision$
- */
-public interface NamespaceScoped extends NodeEx
-{
-    /**
-     * Returns the "local part" of the object's scoped name, without
-     * any namespace prefix.
-     */
-    public String	getLocalName ();
-
-    /**
-     * Return the XML namespace name (a URI) associated with this object,
-     * or null for the case of the default document namespace.  This is
-     * computed from this node and its ancestors.
-     *
-     * @exception IllegalStateException Thrown when the namespace
-     *	prefix for this element is not known.
-     */
-    public String	getNamespace ();
-
-    /**
-     * Returns any prefix of the object's name.  This is only a
-     * context-sensitive alias for the namespace URI.  If the name
-     * is unqualified (e.g. <em>template</em> vs <em>xsl:template</em>),
-     * the null string is returned.
-     *
-     * <P> The URI corresponding to that prefix may be retrieved by
-     * getting the inherited value of the attribute named
-     * <em>"xmlns:" + getPrefix ()</em> if the prefix is not null;
-     * if there is no value for this URI, that indicates an error.
-     * If the prefix is null, the URI is the inherited value of the
-     * attribute named <em>"xmlns"</em>; if there is no value for
-     * that URI, the default namespace has not been defined.
-     *
-     * @see #setPrefix
-     */
-    public String	getPrefix ();
-
-    /**
-     * Assigns a prefix to be used for the object's name.  This method
-     * should be used with care, primarily to "patch up" elements after
-     * they have been moved to a context where the correct namespace may
-     * call for a different prefix.  This method does not check whether
-     * the prefix is declared.  The return value of <em>getNodeName</em>
-     * may change, if this prefix was not the one being used.
-     *
-     * <P> To assign the URI associated with this prefix, declare the
-     * prefix by defining a value for the <em>"xmlns" + prefix</em>
-     * attribute for this node's element or an ancestor element.  For
-     * the null prefix, give a value for the <em>"xmlns"</em> attribute
-     * instead.  All non-null prefixes must be declared.
-     *
-     * @see #getPrefix
-     *
-     * @param prefix null to remove any prefix, otherwise the unqualified
-     *	name prefix to be be used.
-     */
-//XXX modify this for DOM2
-    public void		setPrefix (String prefix);
-
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/NamespacedNode.java b/src/whiteboard/org/apache/xerces/tree/NamespacedNode.java
deleted file mode 100644
index 806075e..0000000
--- a/src/whiteboard/org/apache/xerces/tree/NamespacedNode.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import org.w3c.dom.*;
-import org.apache.xerces.tree.XmlNames;
-
-/**
- * This adds the notion of namespaces to the ParentNode class for certain
- * types of nodes such as DOM Element and Attr nodes.
- *
- * @author Edwin Goei
- * @version $Revision$
- */
-abstract class NamespacedNode extends ParentNode {
-    // Here "name" corresponds to "QName" in the XML Namespaces REC
-    protected String name;
-    protected String namespaceURI;
-
-    /**
-     * The namespace URI of this node, or <code>null</code> if it is
-     * unspecified.  This is not a computed value.
-     *
-     * @since DOM Level 2
-     */
-    public String getNamespaceURI() {
-        return namespaceURI;
-    }
-
-    /**
-     * The namespace prefix of this node, or <code>null</code> if it is
-     * unspecified.
-     *
-     * @since DOM Level 2
-     */
-    public String getPrefix() {
-        return XmlNames.getPrefix(name);
-    }
-
-    /**
-     * Sets the namespace prefix of this node.
-     *
-     * @since DOM Level 2
-     */
-    public void setPrefix(String prefix) throws DOMException {
-        if (readonly) {
-            throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
-        }
-
-	int index = name.indexOf(':');
-
-        // prefix == null implies reset to no default namespace
-	if (prefix == null) {
-	    if (index >= 0) {
-	    	name = name.substring(index + 1);
-            }
-	    return;
-	}
-
-        // Replace or add new prefix
-   	StringBuffer tmp = new StringBuffer(prefix);
-	tmp.append(':');
-	if (index < 0 ) {
-	    tmp.append(name);
-	} else {
-	    tmp.append(name.substring(index + 1));
-        }
-	name = tmp.toString();
-    }
-
-    /**
-     * Returns the local part of the qualified name of this node.
-     *
-     * @since DOM Level 2
-     */
-    public String getLocalName() {
-        return XmlNames.getLocalPart(name);
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/NodeBase.java b/src/whiteboard/org/apache/xerces/tree/NodeBase.java
deleted file mode 100644
index a1d0307..0000000
--- a/src/whiteboard/org/apache/xerces/tree/NodeBase.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-
-import java.io.Writer;
-import java.io.IOException;
-import java.util.Locale;
-
-import org.w3c.dom.*;
-
-
-/**
- * Base class for DOM parse tree nodes which may appear in XmlDocument nodes.
- * This implements "parented by" and "owning document" relationships.  If
- * the parent is not null, this also supports sibling relationships through
- * that parent.  Children may be directly accessed through this class,
- * although it is subclasses which implement that access.
- *
- * @author David Brownell
- * @version $Revision$
- */
-// not public ... javadoc looks a bit odd (hidden base class)
-// but it's only subclassable within this package anyway
-abstract class NodeBase
-    implements Node, NodeEx, NodeList, XmlWritable
-{
-    private ParentNode	parent;
-    private int		parentIndex = -1;	// cache
-
-    // package private for speed ...
-    XmlDocument		ownerDocument;
-    boolean		readonly;
-        
-    /**
-     * Constructs a node which will later have its parent set
-     * by some other member of this package.
-     */
-    // package private 
-    NodeBase () { }
-        
-    /* Returns the node's parent; typesafe convenience rtn. */
-    // package private ... 
-    ParentNode getParentImpl () { return parent; }
-
-    /* not public yet ... */
-    // package private
-    public boolean isReadonly ()
-	{ return readonly; }
-
-    /* not public yet ... */
-    // package private
-    public void setReadonly (boolean deep)
-    {
-	readonly = true;
-	if (deep) {
-	    TreeWalker	walker = new TreeWalker (this);
-	    Node	next;
-	    while ((next = walker.getNext ()) != null)
-		((NodeBase)next).setReadonly (false);
-	}
-    }
-    
-    /**
-     * Returns the language id (value of <code>xml:lang</code>
-     * attribute) applicable to this node, if known.  Traces up
-     * through ancestors as needed.
-     */
-    public String getLanguage () {
-	return getInheritedAttribute ("xml:lang");
-    }
-
-    /**
-     * Returns the value of a given attribute, tracing up through
-     * ancestors if needed.  In the XML standard, two attributes are
-     * inherited:  <em>xml:lang</em> and <em>xml:space</em>.  This
-     * mechanism can also be involved with Cascading Style Sheets (CSS).
-     * The current version of XML Namespaces also uses inheritance.
-     *
-     * @param name identifies the attribute; colons may be included,
-     *	but namespace prefixes are not interpreted
-     * @return the value of the inherited attribute, or null if
-     *	no value was inherited.
-     */
-    public String getInheritedAttribute (String name)
-    {
-	NodeBase	current = this;
-	Attr		value = null;
-
-	do {
-	    if (current instanceof ElementNode) {
-		ElementNode	e = (ElementNode) current;
-
-		if ((value = e.getAttributeNode (name)) != null)
-		    break;
-	    }
-	    current = current.getParentImpl ();
-	} while (current != null);
-	if (value != null)
-	    return value.getValue ();
-	return null;
-    }
-
-    /**
-     * Returns the value of a given attribute, tracing up through
-     * ancestors if needed.  This version accounts for namespaces,
-     * so that the prefix used to identify the namespace of any
-     * particular attribute is ignored when returning its value.
-     *
-     * @param namespace URI associated with the namespace, or null
-     *	to indicate the default namespace
-     * @param name colon-free "local part" of the attribute name
-     * @return the value of the inherited attribute, or null if
-     *	no value was inherited.
-     */
-    public String getInheritedAttribute (String namespace, String name)
-    {
-	NodeBase	current = this;
-	Attr		value = null;
-
-	do {
-	    if (current instanceof ElementNode) {
-		ElementNode	e = (ElementNode) current;
-
-		if ((value = e.getAttributeNode (namespace, name)) != null)
-		    break;
-	    }
-	    current = current.getParentImpl ();
-	} while (current != null);
-	if (value != null)
-	    return value.getValue ();
-	return null;
-    }
-
-    /**
-     * Does nothing; this type of node has no children.
-     */
-    public void writeChildrenXml (XmlWriteContext context) throws IOException
-    {
-    }
-
-    // DOM support from W3C recommendation
-
-    /**
-     * <b>DOM:</b> Returns the node's parent.  This will be null in cases such
-     * as newly created or removed nodes, and for attributes, fragments,
-     * and documents.
-     */
-    public Node getParentNode () {
-	return parent;
-    }
-
-
-    /*
-     * Assigns the node's parent, and remove it from its current parent.
-     * The caller is responsible for letting the new parent know about
-     * this child by inserting it into the set of children at the
-     * appropriate place, if it's not null.
-     *
-     * <P> Note that this method, of necessity, involves the DOM being in
-     * an internally inconsistent state, either with the new parent not yet
-     * knowing about its child-to-be after this call, or this node not
-     * knowing its true parent before the call.  That's why it's not a
-     * public API, here or in DOM.
-     */
-    void setParentNode (ParentNode arg, int index)
-    throws DOMException
-    {
-	if (parent != null && arg != null)
-	    parent.removeChild (this);
-	parent = arg;
-	parentIndex = index;
-    }
-
-        
-    // assigns the owner of this document
-    void setOwnerDocument (XmlDocument doc)
-    {
-	ownerDocument = doc;
-    }
-
-    /**
-     * <b>DOM:</b> Returns the document to which this node belongs.
-     */
-    public Document getOwnerDocument ()
-    {
-	return ownerDocument;
-    }
-
-
-    /**
-     * <b>DOM:</b>  Returns false.
-     * Overridden by subclasses which support children.
-     */
-    public boolean hasChildNodes() { return false; }
-
-    /**
-     * <b>DOM:</b>  does nothing; overridden by subclasses as needed.
-     */
-    public void setNodeValue (String value)
-    {
-	if (readonly)
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-    }
-    
-    /**
-     * <b>DOM:</b>  Returns null; overridden by subclasses as needed.
-     */
-    public String getNodeValue ()
-	{ return null; }
-	
-    /**
-     * <b>DOM:</b>  Returns null.
-     * Overridden by subclasses which support children.
-     */
-    public Node getFirstChild () { return null; }
-    
-    
-    /**
-     * <b>DOM:</b>  Returns zero.
-     * Overridden by subclasses which support children.
-     */
-    public int getLength () { return 0; }
-
-
-    /**
-     * <b>DOM:</b>  Returns null.
-     * Overridden by subclasses which support children.
-     */
-    public Node item (int i) { return null; }
-
-
-    /**
-     * <b>DOM:</b> Returns an object which permits "live" access to all
-     * this node's children.
-     *
-     * <P> In this implementation, nodes provide such access without
-     * needing another node as an intermediary; "this" is returned.
-     */
-    public NodeList           getChildNodes ()
-	{ return this; }
-
-    /**
-     * <b>DOM:</b>  returns null.
-     * Overridden by subclasses which support children.
-     */
-    public Node               getLastChild ()
-	{ return null; }
-
-    /**
-     * <b>DOM:</b>  Throws a HIERARCHY_REQUEST_ERR DOMException.
-     * Overridden by subclasses which support children.
-     * @exception DOMException thrown always.
-     */
-    public Node appendChild (Node newChild)
-    throws DOMException
-	{ throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR); }
-
-    /**
-     * <b>DOM:</b>  Throws a HIERARCHY_REQUEST_ERR DOMException.
-     * Overridden by subclasses which support children.
-     * @exception DOMException thrown always.
-     */
-    public Node insertBefore (Node newChild, Node refChild)
-    throws DOMException
-	{ throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR); }
-
-    /**
-     * <b>DOM:</b>  Throws a HIERARCHY_REQUEST_ERR DOMException.
-     * Overridden by subclasses which support children.
-     * @exception DOMException thrown always.
-     */
-    public Node replaceChild (Node newChild, Node refChild)
-    throws DOMException
-	{ throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR); }
-
-    /**
-     * <b>DOM:</b>  Throws a HIERARCHY_REQUEST_ERR DOMException.
-     * Overridden by subclasses which support children.
-     * @exception DOMException thrown always.
-     */
-    public Node removeChild (Node oldChild)
-    throws DOMException
-	{ throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR); }
-
-    
-    /**
-     * <b>DOM:</b>  Returns the node immediately following this node in a
-     * breadth first traversal of the tree, or null if there is no
-     * such sibling.  In this implementation, sibling access from a
-     * node is slower than indexed access from its parent.
-     */
-    public Node getNextSibling ()
-    {
-	if (parent == null)
-	    return null;
-	if (parentIndex < 0 || parent.item (parentIndex) != this)
-	    parentIndex = parent.getIndexOf (this);
-	return parent.item (parentIndex + 1);
-    }
-
-    /**
-     * <b>DOM:</b>  Returns the node immediately preceding this node in a
-     * breadth first traversal of the tree, or null if there is no
-     * such sibling.  In this implementation, sibling access from a
-     * node is slower than indexed access from its parent.
-     */
-    public Node getPreviousSibling ()
-    {
-	if (parent == null)
-	    return null;
-	if (parentIndex < 0 || parent.item (parentIndex) != this)
-	    parentIndex = parent.getIndexOf (this);
-	return parent.item (parentIndex - 1);
-    }
-
-    /**
-     * <b>DOM:</b> returns null.
-     * Overridden by the ElementNode subclass.
-     */
-    public NamedNodeMap       getAttributes ()
-	{ return null; }
-
-    /**
-     * <b>DOM2:</b> noop.
-     * @since DOM Level 2
-     * Overridden by subclasses that need to support normalization.
-     */
-    public void normalize() {
-    }
-
-    /**
-     * <b>DOM2:</b>
-     * @since DOM Level 2
-     */
-    public boolean supports(String feature, String version) {
-        return XmlDocument.hasFeature0(feature, version);
-    }
-
-    /**
-     * <b>DOM2:</b> returns null.
-     * Overridden by subclasses that support namespaces, ie. ElementNode and
-     * AttributeNode.
-     */
-    public String getNamespaceURI() {
-        return null;
-    }
-
-    /**
-     * <b>DOM2:</b> returns null.
-     * Overridden by subclasses that support namespaces.
-     */
-    public String getPrefix() {
-        return null;
-    }
-
-    /**
-     * <b>DOM2:</b> throws DOMException.NAMESPACE_ERR
-     * Overridden by subclasses that support namespaces.
-     */
-    public void setPrefix(String prefix) throws DOMException {
-	throw new DomEx(DomEx.NAMESPACE_ERR);
-    }
-
-    /**
-     * <b>DOM2:</b> returns null.
-     * Overridden by subclasses that support namespaces.
-     */
-    public String getLocalName() {
-        return null;
-    }
-
-    public int getIndexOf (Node maybeChild)
-	{ return -1; }
-
-    /*
-     * Gets the messages from the resource bundles for the given messageId.
-     */
-    String getMessage (String messageId) {
-   	return getMessage (messageId, null);
-    }
-
-    /*
-     * Gets the messages from the resource bundles for the given messageId
-     * after formatting it with the parameters passed to it.
-     */
-    String getMessage (String messageId, Object[] parameters) {
-        Locale locale;
-
-	if (this instanceof XmlDocument)
-	    locale = ((XmlDocument)this).getLocale ();
-	else if (ownerDocument == null)
-	    locale = Locale.getDefault ();	// sigh
-	else
-	    locale = ownerDocument.getLocale ();
-	return XmlDocument.catalog.getMessage (locale, messageId, parameters);
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/NodeEx.java b/src/whiteboard/org/apache/xerces/tree/NodeEx.java
deleted file mode 100644
index ee44d1e..0000000
--- a/src/whiteboard/org/apache/xerces/tree/NodeEx.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import org.w3c.dom.Node;
-
-
-/**
- * This interface defines accessors to inherited attributes of nodes,
- * and provides support for using XML Namespaces.
- *
- * @author David Brownell
- * @version $Revision$
- */
-public interface NodeEx extends Node, XmlWritable
-{
-    /**
-     * Returns the value of a given attribute, tracing up through
-     * ancestors if needed.  In the XML standard, two attributes are
-     * inherited:  <em>xml:lang</em> and <em>xml:space</em>.  A very
-     * similar mechanism is involved with Cascading Style Sheets (CSS).
-     * XML Namespaces also use inheritance, using attributes with
-     * names like <em>xmlns:foo</em> to declare namespace prefixes.
-     *
-     * @param name The name of the attribute to be found.  Colons in
-     *	this are ignored.
-     * @return the value of the identified attribute, or null if no
-     *	such attribute is found.
-     */
-    public String getInheritedAttribute (String name);
-
-    /**
-     * Returns the value of a given attribute, tracing up through
-     * ancestors if needed and conforming to the XML Namespaces
-     * draft for associating URIs with name prefixes.
-     *
-     * @param uri The namespace for the name; may be null to indicate
-     *	the document's default namespace.
-     * @param name The "local part" of the name, without a colon.
-     * @return the value of the identified attribute, or null if no
-     *	such attribute is found.
-     */
-    public String getInheritedAttribute (String uri, String name);
-
-    /**
-     * Returns the language id (value of <code>xml:lang</code>
-     * attribute) applicable to this node, if known.  Traces up
-     * through ancestors as needed.
-     * @return the value of the <em>xml:lang</em> attribute, or
-     *  null if no such attribute is found.
-     */
-    public String getLanguage ();
-
-    /**
-     * Returns the index of the node in the list of children, such
-     * that <em>item()</em> will return that child.
-     *
-     * @param maybeChild the node which may be a child of this one
-     * @return the index of the node in the set of children, or
-     *	else -1 if that node is not a child of this node.
-     */
-    public int getIndexOf (Node maybeChild);
-
-    /**
-     * Sets the node to be readonly; applies recursively to the children
-     * of this node if the parameter is true.
-     *
-     * @param deep If <code> true </code> recursively set the nodes in the
-     * subtree under the current node to be read only.
-     * If <code> false </code> then set only the current node to be
-     * readonly
-     */
-    public void setReadonly (boolean deep);
-
-    /**
-     * Method to allow easy determination of whether a node is read only.
-     *
-     * @return <code> true </code> if the node is read only
-     */
-    public boolean isReadonly ();
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/PINode.java b/src/whiteboard/org/apache/xerces/tree/PINode.java
deleted file mode 100644
index 00518d1..0000000
--- a/src/whiteboard/org/apache/xerces/tree/PINode.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-
-import java.io.Writer;
-import java.io.IOException;
-
-import org.w3c.dom.*;
-
-
-/**
- * Node representing an XML processing instruction.
- *
- * <P> <em>Functionality to restore in some other way: </em>
- *
- * As a convenience function, the instruction data may optionally
- * be parsed as element attributes are parsed.  There is no requirement
- * to use this particular syntax for instruction data.
- *
- * @author David Brownell
- * @version $Revision$
- */
-final
-//public
-class PINode extends NodeBase implements ProcessingInstruction
-{
-    private String      target;
-    private char	data [];
-        
-    /** Constructs a processing instruction node. */
-    public PINode () { }
-
-    /** Constructs a processing instruction node. */
-    public PINode (String target, String text)
-    {
-	data = text.toCharArray ();
-        this.target = target;
-    }
-
-    PINode (String target, char buf [], int offset, int len)
-    {
-	data = new char [len];
-	System.arraycopy (buf, offset, data, 0, len);
-        this.target = target;
-    }
-
-    /** DOM:  Returns the PROCESSING_INSTRUCTION_NODE node type. */
-    public short getNodeType () { return PROCESSING_INSTRUCTION_NODE; }
-
-    /** DOM:  Returns the processor the instruction is directed to. */
-    public String getTarget () { return target; }
-
-    /** DOM:  Assigns the processor the instruction is directed to. */
-    public void setTarget (String target) { this.target = target; }
-
-    /** DOM: Returns the text data as a string. */
-    public String getData () { return new String (data); }
-
-    /** DOM: Assigns the text data. */
-    public void setData (String data) { 
-        if (isReadonly ())
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-    
-        this.data = data.toCharArray (); 
-    }
-
-    /** DOM: Returns the text data as a string. */
-    public String getNodeValue () { return getData (); }
-
-    /** DOM: Assigns the text data. */
-    public void setNodeValue (String data) { setData (data); }
-
-    /**
-     * Writes the processing instruction as well formed XML text.
-     *
-     * <P> <em> Doesn't currently check for the <b>?&gt;</b> substrings
-     * in PI data, which are illegal </em>
-     */
-    public void writeXml (XmlWriteContext context) throws IOException
-    {
-	Writer	out = context.getWriter ();
-
-        out.write ("<?");
-        out.write (target);
-        if (data != null) {
-            out.write (' ');
-            out.write (data);
-        }
-        out.write ("?>");
-    }
-
-    /** Returns a new processing instruction with the same content as this. */
-    public Node cloneNode (boolean deep) { 
-    	PINode retval = new PINode (target, data, 0, data.length); 
-	retval.setOwnerDocument ((XmlDocument) this.getOwnerDocument ());
-	return retval;
-    }
-
-    /** Returns the PI target name. */
-    public String getNodeName () { return target; }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/ParentNode.java b/src/whiteboard/org/apache/xerces/tree/ParentNode.java
deleted file mode 100644
index f3926f6..0000000
--- a/src/whiteboard/org/apache/xerces/tree/ParentNode.java
+++ /dev/null
@@ -1,818 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.xml.sax.SAXException;
-
-import org.w3c.dom.*;
-
-
-/**
- * This adds an implementation of "parent of" relationships to the NodeBase
- * class.  It implements operations for maintaining a set of children,
- * providing indexed access to them, and writing them them out as text.
- *
- * <P> The NodeList it implements to describe its children is "live", as
- * required by DOM.  That means that indexed accesses by applications must
- * handle cases associated with unstable indices and lengths.  Indices
- * should not be stored if they can be invalidated by changes, including
- * changes made by other threads.
- *
- * @author David Brownell
- * @version $Revision$
- */
-// not public ... javadoc looks a bit odd (hidden base class)
-// but it's only subclassable within this package anyway
-abstract class ParentNode
-    extends NodeBase
-    implements XmlReadable
-{
-    private NodeBase		children [];
-    private int			length;
-
-    /**
-     * Builds a ParentNode, which can have children that are
-     * subclasses of NodeBase.
-     */
-    // package private
-    ParentNode () { }
-
-    /**
-     * Called to minimize space utilization.  Affects only
-     * this node; children must be individually trimmed.
-     */
-    public void trimToSize ()
-    {
-	if (length == 0)
-	    children = null;
-        else if (children.length != length) {
-	    NodeBase	temp [] = new NodeBase [length];
-
-            System.arraycopy (children, 0, temp, 0, length);
-	    children = temp;
-	}
-    }
-
-    // package private
-    void reduceWaste ()
-    {
-	if (children == null)
-	    return;
-
-	//
-	// Arbitrary -- rather than paying trimToSize() costs
-	// on most elements, we routinely accept some waste but
-	// do try to reduce egregious waste.  Interacts with
-	// the array allocation done in appendChild.
-	//
-	if ((children.length - length) > 6)
-            trimToSize ();
-    }
-
-
-    /**
-     * Writes each of the child nodes.  For element nodes, this adds
-     * whitespace to indent non-text children (it prettyprints) unless
-     * the <em>xml:space='preserve'</em> attribute applies, or the
-     * write context disables prettyprinting.
-     *
-     * @param context describes how the children should be printed
-     */
-    public void writeChildrenXml (XmlWriteContext context) throws IOException
-    {
-	if (children == null)
-	    return;
-
-	int	oldIndent = 0;
-	boolean	preserve = true;
-	boolean	pureText = true;
-
-	if (getNodeType () == ELEMENT_NODE) {
-	    preserve = "preserve".equals (
-		    getInheritedAttribute ("xml:space"));
-	    oldIndent = context.getIndentLevel ();
-	}
-
-	try {
-	    if (!preserve)
-		context.setIndentLevel (oldIndent + 2);
-	    for (int i = 0; i < length; i++) {
-		if (!preserve && children [i].getNodeType () != TEXT_NODE) {
-		    context.printIndent ();
-		    pureText = false;
-		}
-		children [i].writeXml (context);
-	    }
-	} finally {
-	    if (!preserve) {
-		context.setIndentLevel (oldIndent);
-		if (!pureText)
-		    context.printIndent ();		// for ETag
-	    }
-	}
-    }
-
-    /**
-     * Subclasses may override this method, which is called shortly after
-     * the object type is known and before any children are processed.
-     * For elements, attributes are known and may be modified; since
-     * parent context is available, inherited attributes can be seen.
-     *
-     * <P> The default implementation does nothing.
-     *
-     * @param context provides location and error reporting data
-     */
-    public void startParse (ParseContext context)
-    throws SAXException
-    {
-	// nothing
-    }
-
-    /**
-     * Subclasses may override this method, which is called after each
-     * child (text, element, processing instruction) is fully parsed.
-     * Subclassers may substitute, discard, reorder, modify, or otherwise
-     * process the child.  For example, elements which correspond to object
-     * properties may be stored in that way, rather than appended.  The
-     * <em>startParse</em> method has always been called before this.
-     *
-     * <P> The default implementation does nothing.
-     *
-     * @param child the child which has just been completely parsed;
-     *	it is already a child of this node.
-     * @param context provides location and error reporting data
-     */
-    public void doneChild (NodeEx child, ParseContext context)
-    throws SAXException
-    {
-    }
-
-    /**
-     * Subclasses may override this method, which is called shortly after
-     * the object is fully parsed.  The <em>startParse</em> method has
-     * always been called before this, and doneChild will have been called
-     * for each child.
-     *
-     * <P> The default implementation does nothing.
-     *
-     * @param context provides location and error reporting data
-     */
-    public void doneParse (ParseContext context)
-    throws SAXException
-    {
-	// nothing
-    }
-
-
-    // package private -- overridden in implementation classes
-    abstract void checkChildType (int type)
-    throws DOMException;
-
-    // DOM support
-
-
-    /**
-     * <b>DOM:</b>  Returns true if there are children to this node.
-     */
-    final public boolean hasChildNodes ()
-    {
-	return length > 0;
-    }
-
-    /**
-     * <b>DOM:</b>  Returns the first child of this node, else null if there
-     * are no children.
-     */
-    final public Node getFirstChild ()
-    {
-	if (length == 0)
-	    return null;
-	return children [0];
-    }
-    
-    /**
-     * <b>DOM:</b>  Returns the last child of this node, else null if there
-     * are no children.
-     */
-    final public Node getLastChild ()
-    {
-	if (length == 0)
-	    return null;
-	return children [length - 1];
-    }
-
-    /** <b>DOM:</b>  Returns the number of children */
-    final public int getLength ()
-    {
-	return length;
-    }
-
-    /** <b>DOM:</b>  Returns the Nth child, or null */
-    final public Node item (int i)
-    {
-	if (length == 0 || i >= length)
-	    return null;
-	try {
-	    return children [i];
-	} catch (ArrayIndexOutOfBoundsException e) {
-	    return null;
-	}
-    }
-
-    // groups all the "wrong document/implementation" checks
-    private NodeBase checkDocument (Node newChild)
-    throws DOMException
-    {
-	if (newChild == null)
-	    throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-
-	// check for wrong implementation
-	if (!(newChild instanceof NodeBase))
-	    throw new DomEx (DomEx.WRONG_DOCUMENT_ERR);
-
-	Document	owner = newChild.getOwnerDocument ();
-	XmlDocument	myOwner = ownerDocument;
-	NodeBase	child = (NodeBase) newChild;
-
-	// bizarre DOM special case for document
-	if (myOwner == null && this instanceof XmlDocument)
-	    myOwner = (XmlDocument) this;
-
-	// check for wrong document
-	if (owner != null && owner != myOwner)
-	    throw new DomEx (DomEx.WRONG_DOCUMENT_ERR);
-	
-	// permit "unowned" NodeBase children to be added,
-	// e.g. if someone constructs an ElementNode directly
-	if (owner == null) {
-	    child.setOwnerDocument (myOwner);
-	}
-
-        if (child.hasChildNodes ()) {
-    	    for (int i = 0; true; i++) {
-	        Node	node = child.item (i);
-	        if (node == null)
-		    break;
-	        if (node.getOwnerDocument () == null)
-	    	    ((NodeBase)node).setOwnerDocument (myOwner);
-	        else if (node.getOwnerDocument () != myOwner)
-		    throw new DomEx (DomEx.WRONG_DOCUMENT_ERR);
-	    }
-        }
-
-	return child;
-    }
-
-    // makes sure that child isn't an ancestor of this
-    private void checkNotAncestor (Node newChild) throws DOMException
-    {
-	// text, etc ...
-	if (!newChild.hasChildNodes ())
-	    return;
-
-	Node	ancestor = this;
-
-	while (ancestor != null) {
-	    if (newChild == ancestor)
-		throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	    ancestor = ancestor.getParentNode ();
-	}
-    }
-
-    // update mutation count 
-    private void mutated ()
-    {
-	XmlDocument doc = ownerDocument;
-
-	if (doc == null && this instanceof XmlDocument)
-	    doc = (XmlDocument) this;
-	if (doc != null)
-	    doc.mutationCount++;
-    }
-
-    //
-    // When fragments are appended/inserted/replaced, their entire
-    // contents get moved and the fragment becomes empty.
-    //
-    private void consumeFragment (Node fragment, Node before)
-    throws DOMException
-    {
-	ParentNode	frag = (ParentNode) fragment;
-	Node		temp;
-
-	// don't start insertions we can't complete
-	for (int i = 0; (temp = frag.item (i)) != null; i++) {
-	    checkNotAncestor (temp);
-	    checkChildType (temp.getNodeType ());
-	}
-
-	while ((temp = frag.item (0)) != null) 
-	    insertBefore (temp, before);
-    }
-
-    /**
-     * <b>DOM:</b>  Appends the child to the set of this node's children.
-     * The new child must belong to this document.  
-     * 
-     * @param newChild the new child to be appended
-     */
-    public Node appendChild (Node newChild)
-    throws DOMException
-    {
-	NodeBase	child;
-
-	if (readonly)
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-	child = checkDocument (newChild);
-
-	if (newChild.getNodeType () == DOCUMENT_FRAGMENT_NODE) {
-	    consumeFragment (newChild, null);
-	    return newChild;
-	}
-
-	checkNotAncestor (newChild);
-	checkChildType (child.getNodeType ());
-
-	// this is the only place this vector needs allocating,
-	// though it may also need to be grown in insertBefore.
-	// most elements have very few children
-	if (children == null)
-	    children = new NodeBase [3];
-	else if (children.length == length) {
-	    NodeBase temp [] = new NodeBase [length * 2];
-            System.arraycopy (children, 0, temp, 0, length);
-	    children = temp;
-	}
-
-	child.setParentNode (this, length);
-	children [length++] = child;
-	mutated ();
-	return child;
-    }
-
-
-    /**
-     * <b>DOM:</b>  Inserts the new child before the specified child,
-     * which if null indicates appending the new child to the
-     * current set of children.  The new child must belong to
-     * this particular document.
-     *
-     * @param newChild the new child to be inserted
-     * @param refChild node before which newChild is to be inserted
-     */
-    public Node insertBefore (Node newChild, Node refChild)
-    throws DOMException
-    {
-	NodeBase	child;
-
-	if (readonly)
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-	if (refChild == null) 
-	    return appendChild (newChild);
-	if (length == 0)
-	    throw new DomEx (DomEx.NOT_FOUND_ERR);
-
-	child = checkDocument (newChild);
-
-	if (newChild.getNodeType () == DOCUMENT_FRAGMENT_NODE) {
-	    consumeFragment (newChild, refChild);
-	    return newChild;
-	}
-
-	checkNotAncestor (newChild);
-	checkChildType (newChild.getNodeType ());
-
-	// grow array if needed
-	if (children.length == length) {
-	    NodeBase temp [] = new NodeBase [length * 2];
-            System.arraycopy (children, 0, temp, 0, length);
-	    children = temp;
-	}
-
-	for (int i = 0; i < length; i++) {
-	    if (children [i] != refChild)
-		continue;
-	    child.setParentNode (this, i);
-            System.arraycopy (children, i, children, i + 1, length - i);
-	    children [i] = child;
-	    length++;
-	    mutated ();
-	    return newChild;
-	}
-
-	throw new DomEx (DomEx.NOT_FOUND_ERR);
-    }
-
-    /**
-     * <b>DOM:</b>  Replaces the specified child with the new node,
-     * returning the original child or throwing an exception.
-     * The new child must belong to this particular document.
-     *
-     * @param newChild the new child to be inserted
-     * @param refChild node which is to be replaced
-     */
-    public Node replaceChild (Node newChild, Node refChild)
-    throws DOMException
-    {
-	NodeBase	child;
-
-	if (readonly)
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-	if (newChild == null || refChild == null)
-	    throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	if (children == null)
-	    throw new DomEx (DomEx.NOT_FOUND_ERR);
-
-	child = checkDocument (newChild);
-
-	if (newChild.getNodeType () == DOCUMENT_FRAGMENT_NODE) {
-	    consumeFragment (newChild, refChild);
-	    return removeChild (refChild);
-	}
-
-	checkNotAncestor (newChild);
-	checkChildType (newChild.getNodeType ());
-
-	for (int i = 0; i < length; i++) {
-	    if (children [i] != refChild)
-		continue;
-	    child.setParentNode (this, i);
-	    children [i] = child;
-	    ((NodeBase) refChild).setParentNode (null, -1);
-	    mutated ();
-	    return refChild;
-	}
-	throw new DomEx (DomEx.NOT_FOUND_ERR);
-    }
-
-
-    /**
-     * <b>DOM:</b>  removes child if present, returning argument.
-     *
-     * @param oldChild the node which is to be removed
-     */
-    public Node removeChild (Node oldChild)
-    throws DOMException
-    {
-	NodeBase	child;
-
-	if (readonly)
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-	if (!(oldChild instanceof NodeBase))
-	    throw new DomEx (DomEx.NOT_FOUND_ERR);
-	child = (NodeBase) oldChild;
-	for (int i = 0; i < length; i++) {
-	    if (children [i] != child)
-		continue;
-	    if ((i + 1) != length)
-		System.arraycopy (children, i + 1, children, i,
-		    (length - 1) - i);
-	    length--;
-	    children [length] = null;
-	    child.setParentNode (null, -1);
-	    mutated ();
-	    return oldChild;
-	}
-	throw new DomEx (DomEx.NOT_FOUND_ERR);
-    }
-
-
-    /**
-     * <b>DOM:</b>  Returns a "live" list view of the elements below this
-     * one which have the specified tag name.  Because this is "live", this
-     * API is dangerous -- indices are not stable in the face of most tree
-     * updates.  Use a TreeWalker instead.
-     *
-     * @param tagname the tag name to show; or "*" for all elements.
-     * @return list of such elements
-     */
-    public NodeList getElementsByTagName (String tagname)
-    {
-	if ("*".equals (tagname))
-	    tagname = null;
-	return new TagList (tagname); 
-    }
-
-    /**
-     * @since DOM Level 2
-     */
-    public NodeList getElementsByTagNameNS(String namespaceURI,
-                                           String localName) {
-	if ("*".equals(namespaceURI)) {
-	    namespaceURI = null;
-        }
-	if ("*".equals(localName)) {
-	    localName = null;
-        }
-	return new TagListNS(namespaceURI, localName); 
-    }
-
-    //
-    // Slightly optimized to track document mutation count.  For now
-    // we assume that a 32 bit counter won't wrap around, and that
-    // there's no point in caching list length.
-    //
-    class TagList implements NodeList {
-	protected String        tag;
-
-	protected int		lastMutationCount;
-	protected int		lastIndex;
-	protected TreeWalker	lastWalker;
-
-	protected int getLastMutationCount() {
-	    XmlDocument doc = (XmlDocument) getOwnerDocument ();
-	    return (doc == null) ? 0 : doc.mutationCount;
-	}
-
-	TagList (String tag) { this.tag = tag; }
-
-	public Node	item (int i)
-	{
-	    if (i < 0)
-		return null;
-
-	    int temp = getLastMutationCount ();
-
-	    // Can we try to reuse the last walker?
-	    if (lastWalker != null) {
-		if (i < lastIndex || temp != lastMutationCount)
-		    lastWalker = null;
-	    }
-
-	    // if not, get a new one ...
-	    if (lastWalker == null) {
-		lastWalker = new TreeWalker (ParentNode.this);
-		lastIndex = -1;
-		lastMutationCount = temp;
-	    }
-
-	    if (i == lastIndex)
-		return lastWalker.getCurrent ();
-
-	    Node	node = null;
-
-	    while (i > lastIndex
-		    && (node = lastWalker.getNextElement (tag)) != null)
-		lastIndex++;
-	    return node;
-	}
-
-	public int	getLength ()
-	{
-	    TreeWalker	walker = new TreeWalker (ParentNode.this);
-	    Node	node = null;
-	    int		retval;
-
-	    for (retval = 0;
-		    (node = walker.getNextElement (tag)) != null;
-		    retval++)
-		continue;
-	    return retval;
-	}
-    }
-
-    // Namespace version
-    // XXX Ugly: much code in common with superclass
-    class TagListNS extends TagList {
-	private String		namespaceURI;
-
-	TagListNS(String namespaceURI, String tag) {
-            super(tag);
-            this.namespaceURI = namespaceURI;
-        }
-
-	public Node item(int i)	{
-	    if (i < 0) {
-		return null;
-            }
-
-	    int temp = getLastMutationCount();
-
-	    // Can we try to reuse the last walker?
-	    if (lastWalker != null) {
-		if (i < lastIndex || temp != lastMutationCount) {
-		    lastWalker = null;
-                }
-	    }
-
-	    // if not, get a new one ...
-	    if (lastWalker == null) {
-		lastWalker = new TreeWalker(ParentNode.this);
-		lastIndex = -1;
-		lastMutationCount = temp;
-	    }
-
-	    if (i == lastIndex) {
-		return lastWalker.getCurrent();
-            }
-
-	    Node node = null;
-
-	    while (i > lastIndex
-                   && (node = lastWalker.getNextElement(namespaceURI, tag))
-                   != null) {
-		lastIndex++;
-            }
-	    return node;
-	}
-
-	public int getLength() {
-	    TreeWalker walker = new TreeWalker(ParentNode.this);
-            int count;
-	    for (count = 0; walker.getNextElement(namespaceURI, tag) != null;
-                 count++) {
-                // noop
-            }
-	    return count;
-	}
-    }
-
-
-    /**
-     * Returns the index of the node in the list of children, such
-     * that <em>item()</em> will return that child.
-     *
-     * @param maybeChild the node which may be a child of this one
-     * @return the index of the node in the set of children, or
-     *	else -1 if that node is not a child
-     */
-    final public int getIndexOf (Node maybeChild)
-    {
-	for (int i = 0; i < length; i++)
-	    if (children [i] == maybeChild)
-		return i;
-	return -1;
-    }
-
-
-    /**
-     * @since DOM Level 2
-     * In DOM2, normalize() was generalized and got moved to Node.
-     *
-     * XXX Comments below are old:
-     * <b>DOM2:</b> Merges all adjacent Text nodes in the tree rooted by this
-     * element.  Avoid using this on large blocks of text not separated
-     * by markup such as elements or processing instructions, since it
-     * can require arbitrarily large blocks of contiguous memory.
-     *
-     * <P> As a compatible extension to DOM, this normalizes treatment
-     * of whitespace except when the <em>xml:space='preserve'</em>
-     * attribute value applies to a node.  All whitespace is normalized
-     * to one space.  This ensures that text which is pretty-printed and
-     * then reread (and normalized) retains the same content. </P>
-     */
-    public void normalize() {
-	boolean	preserve = false;
-	boolean	knowPreserve = false;
-
-	if (readonly) {
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-        }
-
-	for (int i = 0; true; i++) {
-            Node node = item(i);
-	    if (node == null) {
-		break;
-            }
-	    switch (node.getNodeType()) {
-            case ELEMENT_NODE:
-		((Element)node).normalize ();
-		continue;
-                // case CDATA_SECTION_NODE:
-            case TEXT_NODE: {
-                Node node2 = item(i + 1);
-                if (node2 == null || node2.getNodeType() != TEXT_NODE) {
-                    // See if xml:space='preserve' is set...
-                    if (!knowPreserve) {
-                        preserve = "preserve".equals(
-                            getInheritedAttribute("xml:space"));
-                        knowPreserve = true;
-                    }
-
-                    // ... and if not, normalize whitespace
-                    if (!preserve) {
-                        char[] buf = ((TextNode)node).data;
-
-                        // XXX this isn't supposed to happen
-                        if (buf == null || buf.length == 0) {
-                            removeChild(node);
-                            i--;
-                            continue;
-                        }
-
-                        int current = removeWhiteSpaces(buf);
-
-                        // compact if it shrank
-                        if (current != buf.length) {
-                            char[] tmp = new char[current];
-                            System.arraycopy(buf, 0, tmp, 0, current);
-                            ((TextNode)node).data = tmp;
-                        }
-                    }
-                    continue;
-                }
-		    
-                ((TextNode) node).joinNextText();
-                i--;
-                continue;
-            }
-            default:
-		continue;
-	    }
-	}
-    }
-
-    /*
-     * removes white leading, trailing and extra white spaces from the buffer.
-     * returns the size of the new buf after the white spaces are removed.
-     */
-    public int removeWhiteSpaces(char[] buf) {
-        int current = 0;
-        int j = 0;
-
-        // copy to beginning, normalizing whitespace
-        // (including leading, trailing) to one space
-        while (j < buf.length) {
-            boolean sawSpace = false;
-            char c = buf[j++];
-
-            if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
-                c = ' ';
-                sawSpace = true;
-            }
-            buf[current++] = c;
-            if (sawSpace) {
-                while (j < buf.length) {
-                    c = buf[j];
-                    if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
-                        j++;
-                        continue;
-                    } else {
-                        break;
-                    }
-                }
-            }
-        }
-        return current;
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/ParseContext.java b/src/whiteboard/org/apache/xerces/tree/ParseContext.java
deleted file mode 100644
index c5a7855..0000000
--- a/src/whiteboard/org/apache/xerces/tree/ParseContext.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import java.util.Locale;
-
-import org.xml.sax.*;
-
-/**
- * This interface is used during parsing of XML content to encapsulate
- * information about the location of the parsing event being reported.
- * It is used to report diagnostics for application level problems that
- * relate to the data which was successfuly parsed, and to resolve
- * relative URIs.
- *
- * @author David Brownell
- * @version $Revision$
- */
-public interface ParseContext
-{
-    /**
-     * Returns an error handler that may be used to report problems
-     * of various types:  warnings, recoverable errors, fatal errors.
-     */
-    ErrorHandler getErrorHandler ();
-
-    /**
-     * Returns the preferred locale for diagnostic messsages to be
-     * reported through the error handler.  If this locale is not
-     * supported by the appropriate message catalog, it is suggested
-     * that messages include some sort of diagnostic identifier which
-     * is the same in all locales.
-     */
-    Locale getLocale ();
-
-    /**
-     * Returns a locator object which reports where the parse event
-     * was detected.  The <em>systemId</em> is the base URI to be used
-     * when resolving relative URIs, and other information is used
-     * in diagnostics.
-     */
-    Locator getLocator ();
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/README b/src/whiteboard/org/apache/xerces/tree/README
deleted file mode 100644
index d27042b..0000000
--- a/src/whiteboard/org/apache/xerces/tree/README
+++ /dev/null
@@ -1,3 +0,0 @@
-Integrate crimson DOM to xerces.
-
-
diff --git a/src/whiteboard/org/apache/xerces/tree/Resolver.java b/src/whiteboard/org/apache/xerces/tree/Resolver.java
deleted file mode 100644
index e0e91c8..0000000
--- a/src/whiteboard/org/apache/xerces/tree/Resolver.java
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-
-package org.apache.xerces.tree;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.net.HttpURLConnection;
-import java.util.Hashtable;
-
-import org.xml.sax.*;
-
-
-/**
- * This entity resolver class provides a number of utilities which can help
- * managment of external parsed entities in XML.  These are commonly used
- * to hold markup declarations that are to be used as part of a Document
- * Type Declaration (DTD), or to hold text marked up with XML.
- *
- * <P> Features include: <UL>
- *
- * <LI> Static factory methods are provided for constructing SAX InputSource
- * objects from Files, URLs, or MIME objects.  This eliminates a class of
- * error-prone coding in applications.
- *
- * <LI> Character encodings for XML documents are correctly supported: <UL>
- *
- *	<LI> The encodings defined in the RFCs for MIME content types
- *	(2046 for general MIME, and 2376 for XML in particular), are
- *	supported, handling <em>charset=...</em> attributes and accepting
- *	content types which are known to be safe for use with XML;
- *
- *	<LI> The character encoding autodetection algorithm identified
- *	in the XML specification is used, and leverages all of
- *	the JDK 1.1 (and later) character encoding support.
- *
- *	<LI> The use of MIME typing may optionally be disabled, forcing the
- *	use of autodetection, to support web servers which don't correctly
- *	report MIME types for XML.  For example, they may report text that
- *	is encoded in EUC-JP as being US-ASCII text, leading to fatal
- *	errors during parsing.
- *
- *	<LI> The InputSource objects returned by this class always
- *	have a <code>java.io.Reader</code> available as the "character
- *	stream" property.
- *
- *	</UL>
- *
- * <LI> Catalog entries can map public identifiers to Java resources or
- * to local URLs.  These are used to reduce network dependencies and loads,
- * and will often be used for external DTD components.  For example, packages
- * shipping DTD files as resources in JAR files can eliminate network traffic
- * when accessing them, and sites may provide local caches of common DTDs.
- * Note that no particular catalog syntax is supported by this class, only
- * the notion of a set of entries.
- *
- * </UL>
- *
- * <P> Subclasses can perform tasks such as supporting new URI schemes for
- * URIs which are not URLs, such as URNs (see RFC 2396) or for accessing
- * MIME entities which are part of a <em>multipart/related</em> group
- * (see RFC 2387).  They may also be used to support particular catalog
- * syntaxes, such as the <a href="http://www.oasis-open.org/html/a401.htm">
- * SGML/Open Catalog (SOCAT)</a> which supports the SGML notion of "Formal
- * Public Identifiers (FPIs).
- *
- * @author David Brownell
- * @author Rajiv Mordani
- * @version $Revision$
- */
-public class Resolver implements EntityResolver
-{
-    private boolean		ignoringMIME;
-
-    // table mapping public IDs to (local) URIs
-    private Hashtable		id2uri;
-
-    // tables mapping public IDs to resources and classloaders
-    private Hashtable		id2resource;
-    private Hashtable		id2loader;
-
-    //
-    // table of MIME content types (less attributes!) known
-    // to be mostly "OK" to use with XML MIME entities.  the
-    // idea is to rule out obvious braindamage ("image/jpg")
-    // not the subtle stuff ("text/html") that might actually
-    // be (or become) safe.
-    //
-    private static final String types [] = {
-	"application/xml",
-	"text/xml",
-	"text/plain",
-	"text/html",			// commonly mis-inferred
-	"application/x-netcdf",		// this is often illegal XML
-	"content/unknown"
-    };
-
-    /** Constructs a resolver. */
-    public			Resolver () { }
-    
-    /**
-     * Returns an input source, using the MIME type information and URL
-     * scheme to statically determine the correct character encoding if
-     * possible and otherwise autodetecting it.  MIME carefully specifies
-     * the character encoding defaults, and how attributes of the content
-     * type can change it.  XML further specifies two mandatory encodings
-     * (UTF-8 and UTF-16), and includes an XML declaration which can be
-     * used to internally label most documents encoded using US-ASCII
-     * supersets (such as Shift_JIS, EUC-JP, ISO-2022-*, ISO-8859-*, and
-     * more).
-     *
-     * <P> This method can be used to access XML documents which do not
-     * have URIs (such as servlet input streams, or most JavaMail message
-     * entities) and to support access methods such as HTTP POST or PUT.
-     * (URLs normally return content using the GET method.)
-     *
-     * <P> <em> The caller should set the system ID in order for relative URIs
-     * found in this document to be interpreted correctly.</em> In some cases,
-     * a custom resolver will need to be used; for example, documents
-     * may be grouped in a single MIME "multipart/related" bundle, and
-     * relative URLs would refer to other documents in that bundle.
-     *
-     * @param contentType The MIME content type for the source for which
-     *	an InputSource is desired, such as <em>text/xml;charset=utf-8</em>.
-     * @param stream The input byte stream for the input source.
-     * @param checkType If true, this verifies that the content type is known
-     *	to support XML documents, such as <em>application/xml</em>.
-     * @param scheme Unless this is "file", unspecified MIME types
-     *	default to US-ASCII.  Files are always autodetected since most
-     *	file systems discard character encoding information.
-     */
-    public static InputSource createInputSource (
-	String		contentType,
-	InputStream	stream,
-	boolean		checkType,
-	String		scheme
-    ) throws IOException
-    {
-        InputSource     retval;
-	String		charset = null;
-	    
-	if (contentType != null) {
-	    int		index;
-
-	    contentType = contentType.toLowerCase ();
-	    index = contentType.indexOf (';');
-	    if (index != -1) {
-		String	attributes;
-
-		attributes = contentType.substring (index + 1);
-		contentType = contentType.substring (0, index);
-
-		// use "charset=..." if it's available
-		index = attributes.indexOf ("charset");
-		if (index != -1) {
-		    attributes = attributes.substring (index + 7);
-		    // strip out subsequent attributes
-		    if ((index = attributes.indexOf (';')) != -1)
-			attributes = attributes.substring (0, index);
-		    // find start of value
-		    if ((index = attributes.indexOf ('=')) != -1) {
-			attributes = attributes.substring (index + 1);
-			// strip out rfc822 comments
-			if ((index = attributes.indexOf ('(')) != -1)
-			    attributes = attributes.substring (0, index);
-			// double quotes are optional
-			if ((index = attributes.indexOf ('"')) != -1) {
-			    attributes = attributes.substring (index + 1);
-			    attributes = attributes.substring (0,
-				    attributes.indexOf ('"'));
-			}
-			charset = attributes.trim ();
-			// XXX "\;", "\)" etc were mishandled above
-		    }
-		}
-	    }
-
-	    //
-	    // Check MIME type.
-	    //
-	    if (checkType) {
-		boolean isOK = false;
-		for (int i = 0; i < types.length; i++)
-		    if (types [i].equals (contentType)) {
-			isOK = true;
-			break;
-		    }
-		if (!isOK)
-		    throw new IOException ("Not XML: " + contentType);
-	    }
-
-	    //
-	    // "text/*" MIME types have hard-wired character set
-	    // defaults, as specified in the RFCs.  For XML, we
-	    // ignore the system "file.encoding" property since
-	    // autodetection is more correct.
-	    //
-	    if (charset == null) {
-		contentType = contentType.trim ();
-		if (contentType.startsWith ("text/")) {
-		    if (!"file".equalsIgnoreCase (scheme))
-			charset = "US-ASCII";
-		}
-		// "application/*" has no default
-	    }
-	}
-
-	retval = new InputSource (XmlReader.createReader (stream, charset));
-	retval.setByteStream (stream);
-	retval.setEncoding (charset);
-	return retval;
-    }
-
-
-    /**
-     * Creates an input source from a given URI.
-     *
-     * @param uri the URI (system ID) for the entity
-     * @param checkType if true, the MIME content type for the entity
-     *	is checked for document type and character set encoding.
-     */
-    static public InputSource createInputSource (URL uri, boolean checkType)
-    throws IOException
-    {
-	URLConnection	conn = uri.openConnection ();
-	if (conn instanceof HttpURLConnection) {
-	    int status = ((HttpURLConnection)conn).getResponseCode ();
-	    if ((status >= 400 && status <= 417) ||
-		(status >=500 && status <=505))
-	    {
-	   	throw new IOException ("Error in opening uri " + uri + 
-					"status code=" + status); 
-	    }
-	}
-	InputSource	retval;
-	
-	if (checkType) {
-	    String	contentType = conn.getContentType ();
-	    retval = createInputSource (contentType, conn.getInputStream (),
-		    false, uri.getProtocol ());
-	} else {
-	    retval = new InputSource (
-		    XmlReader.createReader (conn.getInputStream ()));
-	}
-	retval.setSystemId (conn.getURL ().toString ());
-	return retval;
-    }
-
-
-    /**
-     * Creates an input source from a given file, autodetecting
-     * the character encoding.
-     *
-     * @param uri the URI (system ID) for the entity
-     */
-    static public InputSource createInputSource (File file)
-    throws IOException
-    {
-	InputSource	retval;
-	String		path;
-	
-	retval = new InputSource (
-		    XmlReader.createReader (new FileInputStream (file)));
-
-	// On JDK 1.2 and later, simplify this:
-	//	"path = file.toURL ().toString ()".
-	path = file.getAbsolutePath ();
-	if (File.separatorChar != '/')
-	    path = path.replace (File.separatorChar, '/');
-	if (!path.startsWith ("/"))
-	    path = "/" + path;
-	if (!path.endsWith ("/") && file.isDirectory ())
-	    path = path + "/";
-
-	retval.setSystemId ("file:" + path);
-	return retval;
-    }
-
-
-    /**
-     * <b>SAX:</b>
-     * Resolve the given entity into an input source.  If the name can't
-     * be mapped to a preferred form of the entity, the URI is used.  To
-     * resolve the entity, first a local catalog mapping names to URIs is
-     * consulted.  If no mapping is found there, a catalog mapping names
-     * to java resources is consulted.  Finally, if neither mapping found
-     * a copy of the entity, the specified URI is used.
-     *
-     * <P> When a URI is used, <a href="#createInputSource">
-     * createInputSource</a> is used to correctly deduce the character
-     * encoding used by this entity.  No MIME type checking is done.
-     *
-     * @param name Used to find alternate copies of the entity, when
-     *	this value is non-null; this is the XML "public ID".
-     * @param uri Used when no alternate copy of the entity is found;
-     *	this is the XML "system ID", normally a URI.
-     */
-    public InputSource 	resolveEntity (String name, String uri)
-    throws IOException, SAXException
-    {    	    
-	InputSource     retval;        
-	String		mappedURI = name2uri (name);
-	InputStream	stream;
-
-	// prefer explicit URI mappings, then bundled resources...
-	if (mappedURI == null && (stream = mapResource (name)) != null) {
-	    uri = "java:resource:" + (String) id2resource.get (name);
-	    retval = new InputSource (XmlReader.createReader (stream));
-
-	// ...and treat all URIs the same (as URLs for now). 
-	} else {
-	    URL			url;
-	    URLConnection	conn;
-	    
-	    if (mappedURI != null)
-		uri = mappedURI;
-	    else if (uri == null)
-		return null;
-
-	    url = new URL (uri);
-	    conn = url.openConnection ();
-	    uri = conn.getURL ().toString ();
-	    // System.out.println ("++ URI: " + url);
-	    if (ignoringMIME)
-		retval = new InputSource (
-			XmlReader.createReader (conn.getInputStream ()));
-	    else {
-		String		contentType = conn.getContentType ();
-		retval = createInputSource (contentType,
-			conn.getInputStream (),
-			false, url.getProtocol ());
-	    }
-	}
-	retval.setSystemId (uri);
-	retval.setPublicId (name);
-	return retval;
-    }
-
-
-    /**
-     * Returns true if this resolver is ignoring MIME types in the documents
-     * it returns, to work around bugs in how servers have reported the
-     * documents' MIME types.
-     */
-    public boolean isIgnoringMIME ()
-	{ return ignoringMIME; }
-
-    /**
-     * Tells the resolver whether to ignore MIME types in the documents it
-     * retrieves.  Many web servers incorrectly assign text documents a
-     * default character encoding, even when that is incorrect.  For example,
-     * all HTTP text documents default to use ISO-8859-1 (used for Western
-     * European languages), and other MIME sources default text documents
-     * to use US-ASCII (a seven bit encoding).  For XML documents which
-     * include text encoding declarations (as most should do), these server
-     * bugs can be worked around by ignoring the MIME type entirely.
-     */
-    public void setIgnoringMIME (boolean value)
-	{ ignoringMIME = value; }
-
-
-    // maps the public ID to an alternate URI, if one is registered
-    private String name2uri (String publicId)
-    {
-	if (publicId == null || id2uri == null)
-	    return null;
-	return (String) id2uri.get (publicId);
-    }
-
-
-    /**
-     * Registers the given public ID as corresponding to a particular 
-     * URI, typically a local copy.  This URI will be used in preference
-     * to ones provided as system IDs in XML entity declarations.  This
-     * mechanism would most typically be used for Document Type Definitions
-     * (DTDs), where the public IDs are formally managed and versioned.
-     *
-     * @param publicId The managed public ID being mapped
-     * @param uri The URI of the preferred copy of that entity
-     */
-    public void registerCatalogEntry (
-	String		publicId,
-	String		uri
-    )
-    {
-	if (id2uri == null)
-	    id2uri = new Hashtable (17);
-	id2uri.put (publicId, uri);
-    }
-
-
-    // return the resource as a stream
-    private InputStream mapResource (String publicId)
-    {
-	// System.out.println ("++ PUBLIC: " + publicId);
-	if (publicId == null || id2resource == null)
-	    return null;
-
-	String		resourceName = (String) id2resource.get (publicId);
-	ClassLoader	loader = null;
-
-	if (resourceName == null)
-	    return null;
-	// System.out.println ("++ Resource: " + resourceName);
-	
-	if (id2loader != null)
-	    loader = (ClassLoader) id2loader.get (publicId);
-	// System.out.println ("++ Loader: " + loader);
-	if (loader == null)
-	    return ClassLoader.getSystemResourceAsStream (resourceName);
-	return loader.getResourceAsStream (resourceName);
-    }
-
-    /**
-     * Registers a given public ID as corresponding to a particular Java
-     * resource in a given class loader, typically distributed with a
-     * software package.  This resource will be preferred over system IDs
-     * included in XML documents.  This mechanism should most typically be
-     * used for Document Type Definitions (DTDs), where the public IDs are
-     * formally managed and versioned.
-     *
-     * <P> If a mapping to a URI has been provided, that mapping takes
-     * precedence over this one.
-     *
-     * @param publicId The managed public ID being mapped
-     * @param resourceName The name of the Java resource
-     * @param loader The class loader holding the resource, or null if
-     *	it is a system resource.
-     */
-    public void registerCatalogEntry (
-	String		publicId,
-	String		resourceName,
-	ClassLoader	loader
-    )
-    {
-	if (id2resource == null)
-	    id2resource = new Hashtable (17);
-	id2resource.put (publicId, resourceName);
-
-	if (loader != null) {
-	    if (id2loader == null)
-		id2loader = new Hashtable (17);
-	    id2loader.put (publicId, loader);
-	}
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/SimpleElementFactory.java b/src/whiteboard/org/apache/xerces/tree/SimpleElementFactory.java
deleted file mode 100644
index 679f1bb..0000000
--- a/src/whiteboard/org/apache/xerces/tree/SimpleElementFactory.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.Locale;
-
-import org.w3c.dom.*;
-
-
-/**
- * This is a convenience class for creating application-specific elements
- * associated with specified (or default) XML namespaces.  It maintains
- * tables mapping element tag names to classes, and uses them as needed
- * to instantiate classes.  The string <em>*Element</em>, which is not a
- * legal XML element name, may be used to map otherwise unrecognized tags
- * to a particular class.  If this factory is not configured, then all
- * mappings are to the <a href=ElementNode.html>ElementNode</a> class.
- * Erroneous mappings are fatal errors.
- *
- * <P> A suggested XML syntax for recording these bindings, which may
- * in the future be explicitly supported, is: <PRE>
- * <b>&lt;bindings xmlns="..."&gt;</b>
- *     &lt;!-- first, bindings for the "default" namespace --&gt;
- *     <b>&lt;binding tag="..." class="..."/&gt;</b>
- *     &lt;binding <b>tag="*Element"</b> class="..."/&gt;
- *     ...
- *
- *     &lt;!-- then bindings for other namespaces --&gt;
- *     <b>&lt;namespace uri="..."&gt;</b>
- *         &lt;binding tag="..." class="..."/&gt;
- *         ...
- *     <b>&lt;/namespace&gt;</b>
- *
- *     &lt;!-- can specify JAR files for namespaces --&gt;
- *     &lt;namespace uri="..." <b>jar="..."</b>&gt;
- *         &lt;binding tag="..." class="..."/&gt;
- *         ...
- *     &lt;/namespace&gt;
- *     ...
- * <b>&lt;/bindings&gt;</b>
- * </PRE>
- *
- * <P> Note that while most URIs used to identify namespaces will be URLs,
- * such as <em>http://www.example.com/xml/purchasing</em>, some may also
- * be URNs like <em>urn:uuid:221ffe10-ae3c-11d1-b66c-00805f8a2676</em>.
- * You can't assume that the URIs are associated with web-accessible data;
- * they must be treated as being no more than distinguishable strings.
- *
- * <P> Applications classes configuring an element factory will need to
- * provide their own class loader (<code>this.class.getClassLoader</code>)
- * to get the desired behavior in common cases.  Classes loaded via some
- * URL will similarly need to use a network class loader.
- *
- * @author David Brownell
- * @version $Revision$
- */
-public class SimpleElementFactory implements ElementFactory
-{
-    // in the absense of a mapping tied to namespace URI, use these
-    private Dictionary		defaultMapping;
-    private ClassLoader		defaultLoader;
-
-    private String		defaultNs;
-
-    // these hold mappings tied to namespace URIs
-    private Dictionary		nsMappings;
-    private Dictionary		nsLoaders;
-    private Locale 		locale = Locale.getDefault ();
-
-
-    /**
-     * Constructs an unconfigured element factory.
-     */
-    public SimpleElementFactory () { }
-
-    /**
-     * Records a default element name to namespace mapping, for use
-     * by namespace-unaware DOM construction and when a specific
-     * namespace mapping is not available.
-     *
-     * @param dict Keys are element names, and values are either class
-     *	names (interpreted with respect to <em>loader</em>) or class
-     *	objects.  This value may not be null, and the dictionary is
-     *	retained and modified by the factory.
-     * @param loader If non-null, this is used instead of the bootstrap
-     *	class loader when mapping from class names to class objects.
-     */
-    public void addMapping (Dictionary dict, ClassLoader loader)
-    {
-	if (dict == null)
-	    throw new IllegalArgumentException ();
-	defaultMapping = dict;
-	defaultLoader = loader;
-    }
-
-    /**
-     * Records a namespace-specific mapping between element names and
-     * classes.
-     *
-     * @param namespace A URI identifying the namespace for which the
-     *	mapping is defined
-     * @param dict Keys are element names, and values are either class
-     *	names (interpreted with respect to <em>loader</em>) or class
-     *	objects.  This value may not be null, and the dictionary is
-     *	retained and modified by the factory.
-     * @param loader If non-null, this is used instead of the bootstrap
-     *	class loader when mapping from class names to class objects.
-     */
-    public void addMapping (
-	String		namespace,
-	Dictionary	dict,
-	ClassLoader	loader
-    ) {
-	if (namespace == null || dict == null)
-	    throw new IllegalArgumentException ();
-	if (nsMappings == null) {
-	    nsMappings = new Hashtable ();
-	    nsLoaders = new Hashtable ();
-	}
-	nsMappings.put (namespace, dict);
-	if (loader != null)
-	    nsLoaders.put (namespace, loader);
-    }
-
-    /**
-     * Defines a URI to be treated as the "default" namespace.  This
-     * is used only when choosing element classes, and may not be
-     * visible when instances are asked for their namespaces. 
-     */
-    public void setDefaultNamespace (String ns)
-	{ defaultNs = ns; }
-
-    private Class map2Class (
-	String		key,
-	Dictionary	node2class,
-	ClassLoader	loader
-    )
-    {
-	Object		mapResult = node2class.get (key);
-
-	if (mapResult instanceof Class)
-	    return (Class) mapResult;
-	if (mapResult == null)
-	    return null;
-        
-	if (mapResult instanceof String) {
-	    String	className = (String) mapResult;
-	    Class	retval;
-
-	    try {
-		if (loader == null)
-		    retval = Class.forName (className);
-		else
-		    retval = loader.loadClass (className);
-
-		//
-		// We really have no option here.  DOM requires two
-		// bidirectional relationships (parent/child, and
-		// between siblings) and one unidirectional one (nodes
-		// belong to one document) but doesn't provide APIs that
-		// would suffice to maintain them.  So those APIs
-		// must rely on knowledge of the implementation to
-		// which things are connecting.
-		//
-		if (!ElementNode.class.isAssignableFrom (retval))
-		    throw new IllegalArgumentException (getMessage ("SEF-000",
-		    			new Object [] { key, className }));
-		node2class.put (key, retval);
-		return retval;
-		
-	    } catch (ClassNotFoundException e) {
-		throw new IllegalArgumentException (getMessage ("SEF-001",
-			new Object [] { key, className, e.getMessage ()}));
-	    }
-	}
-
-	// another option:  clone elements, resetting parent
-	// and document associations?
-
-	throw new IllegalArgumentException (getMessage ("SEF-002", 
-				new Object [] { key }));
-    }
-
-    private ElementNode doMap (
-	String		tagName,
-	Dictionary	node2class,
-	ClassLoader	loader
-    ) {
-        Class		theClass;
-	ElementNode	retval;
-
-	theClass = map2Class (tagName, node2class, loader);
-	if (theClass == null)
-	    theClass = map2Class ("*Element", node2class, loader);
-	if (theClass == null)
-	    retval = new ElementNode ();
-	else {
-	    try {
-		retval = (ElementNode) theClass.newInstance ();
-	    } catch (Exception e) {
-		    //InstantiationException
-		    //IllegalAccessException
-		throw new IllegalArgumentException (getMessage ("SEF-003",
-			new Object [] {tagName, theClass.getName (),
-					e.getMessage () }));
-	    }
-	}
-	return retval;
-    }
-
-    /**
-     * Creates an element by using the mapping associated with the
-     * specified namespace, or the default namespace as appropriate.
-     * If no mapping associated with that namespace is defined, then
-     * the default mapping is used.
-     *
-     * @param namespace URI for namespace; null indicates use of
-     *	the default namespace, if any.
-     * @param tag element tag, without any embedded colon
-     */
-    public ElementEx createElementEx (String namespace, String tag)
-    {
-	Dictionary	mapping = null;
-
-	if (namespace == null)
-	    namespace = defaultNs;
-
-	if (nsMappings != null)
-	    mapping = (Dictionary) nsMappings.get (namespace);
-	if (mapping == null)
-	    return doMap (tag, defaultMapping, defaultLoader);
-	else
-	    return doMap (tag, mapping,
-		(ClassLoader)nsLoaders.get (namespace));
-    }
-
-    /**
-     * Creates an element by using the default mapping.
-     *
-     * @param tag element tag
-     */
-    public ElementEx createElementEx (String tag)
-    {
-	return doMap (tag, defaultMapping, defaultLoader);
-    }
-
-    /*
-     * Gets the messages from the resource bundles for the given messageId.
-     */
-    String getMessage (String messageId) {
-   	return getMessage (messageId, null);
-    }
-
-    /*
-     * Gets the messages from the resource bundles for the given messageId
-     * after formatting it with the parameters passed to it.
-     */
-    //XXX use the default locale only at this point.
-    String getMessage (String messageId, Object[] parameters) {
-	return XmlDocument.catalog.getMessage (locale, messageId, parameters);
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/TextNode.java b/src/whiteboard/org/apache/xerces/tree/TextNode.java
deleted file mode 100644
index bd509af..0000000
--- a/src/whiteboard/org/apache/xerces/tree/TextNode.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-
-import java.io.Writer;
-import java.io.IOException;
-
-import org.w3c.dom.*;
-
-
-/**
- * Node representing XML text.
- *
- * <P> Subclasses should not currently attempt to modify the
- * representation of content, but may add new methods to support
- * more sophisticated access or manipulation of that content.
- *
- * @author David Brownell
- * @version $Revision$
- */
-// public
-class TextNode extends DataNode implements Text
-{
-    //
-    // XXX Really want a more flexible representation of text than
-    // we have here ... it should be possible to take up only part
-    // of a buffer, and in fact to be able to share one with other
-    // text nodes.  For readonly trees that will reduce the heap
-    // impact; and for editable ones it can facilitate intelligent
-    // editing support.  Text seems more expensive than attributes,
-    // which is quite odd.
-    //
-
-    /**
-     * Constructs a text object with no text and unattached
-     * to any document.
-     */
-    public TextNode () { }
-
-        
-    /**
-     * Constructs text object by copying text from the input buffer.
-     */
-    public TextNode (char buf [], int offset, int len)
-    {
-	super (buf, offset, len);
-    }
-
-    /**
-     * Constructs a text object by copying text from the string.
-     */
-    public TextNode (String s)
-    {
-	super (s);
-    }
-
-    /**
-     * Writes the text, escaping XML metacharacters as needed
-     * to let this text be parsed again without change.
-     */
-    public void writeXml (XmlWriteContext context) throws IOException
-    {
-	Writer	out = context.getWriter ();
-	int	start = 0, last = 0;
-
-	// XXX saw this once -- being paranoid
-	if (data == null)
-	    { System.err.println ("Null text data??"); return; }
-
-	while (last < data.length) {
-	    char c = data [last];
-
-	    //
-	    // escape markup delimiters only ... and do bulk
-	    // writes wherever possible, for best performance
-	    //
-	    // note that character data can't have the CDATA
-	    // termination "]]>"; escaping ">" suffices, and
-	    // doing it very generally helps simple parsers
-	    // that may not be quite correct.
-	    //
-	    if (c == '<') {			// not legal in char data
-		out.write (data, start, last - start);
-		start = last + 1;
-		out.write ("&lt;");
-	    } else if (c == '>') {		// see above
-		out.write (data, start, last - start);
-		start = last + 1;
-		out.write ("&gt;");
-	    } else if (c == '&') {		// not legal in char data
-		out.write (data, start, last - start);
-		start = last + 1;
-		out.write ("&amp;");
-	    }
-	    last++;
-	}
-	out.write (data, start, last - start);
-    }
-
-    /**
-     * Combines this text node with its next sibling to create a
-     * single text node.  If the next node is not text, nothing is
-     * done.  This should be used with care, since large spans of
-     * text may not be efficient to represent.
-     */
-    public void joinNextText ()
-    {
-	Node	next = getNextSibling ();
-	char	tmp [], nextText [];
-
-	if (next == null || next.getNodeType () != TEXT_NODE)
-	    return;
-	getParentNode ().removeChild (next);
-
-	nextText = ((TextNode)next).getText ();
-	tmp = new char [data.length + nextText.length];
-	System.arraycopy (data, 0, tmp, 0, data.length);
-	System.arraycopy (nextText, 0, tmp, data.length, nextText.length);
-	data = tmp;
-    }
-
-
-    // DOM support
-
-    /** DOM: Returns the TEXT_NODE node type constant. */
-    public short getNodeType () { return TEXT_NODE; }
-
-
-    /**
-     * DOM:  Splits this text node into two, returning the part
-     * beginning at <em>offset</em>.  The original node has that 
-     * text removed, and the two nodes are siblings in the natural
-     * order.
-     */
-    public Text splitText (int offset)
-    throws DOMException
-    {
-	TextNode	retval;
-	char		delta [];
-
-        if (isReadonly ())
-	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
-	
-	try {
-		retval = new TextNode (data, offset, data.length - offset);
-	}
-	catch (ArrayIndexOutOfBoundsException ae) {
-		throw new DomEx (DOMException.INDEX_SIZE_ERR);
-	}
-	catch (NegativeArraySizeException nae) {
-		throw new DomEx (DOMException.INDEX_SIZE_ERR);
-	}
-	getParentNode().insertBefore (retval, getNextSibling ());
-	delta = new char [offset];
-	System.arraycopy (data, 0, delta, 0, offset);
-	data = delta;
-	return retval;
-    }
-
-
-    /**
-     * DOM: returns a new text node with the same contents as this one.
-     */
-    public Node cloneNode (boolean deep)
-    {
-    	TextNode retval = new TextNode (data, 0, data.length);
-	retval.setOwnerDocument ((XmlDocument) this.getOwnerDocument ());
-	return retval;
-    }
-
-    /**
-     * DOM:  Returns the string "#text".
-     */
-    public String getNodeName () { return "#text"; }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/TreeWalker.java b/src/whiteboard/org/apache/xerces/tree/TreeWalker.java
deleted file mode 100644
index bec378c..0000000
--- a/src/whiteboard/org/apache/xerces/tree/TreeWalker.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import java.util.Locale;
-
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-
-/**
- * This class implements a preorder depth first walk over the tree rooted
- * at a given DOM node.  The traversal is "live", and terminates either when
- * that given node is reached when climbing back up, or when a null parent
- * node is reached.  It may be restarted via <em>reset()</em>.
- *
- * <P> The way this remains live is to have a "current" node to which the
- * walk is tied.  If the tree is modified, that current node will always
- * still be valid ... even if it is no longer connected to the rest of
- * the document, or if it's reconnected at a different location.  The
- * behavior of tree modifications is specified by DOM, and the interaction
- * with a walker's current node is specified entirely by knowing that only
- * the getNextSibling, getParentNode, and getFirstChild methods are used
- * for walking the tree.
- *
- * <P> For example, if the current branch is cut off, the walk will stop
- * when it tries to access what were parents or siblings of that node.
- * (That is, the walk will continue over the branch that was cut.)  If
- * that is not the intended behaviour, one must change the "current" branch
- * before cutting ... much like avoiding trimming a branch off a real
- * tree if someone is sitting on it.  The <em>removeCurrent()</em>
- * method encapsulates that logic.
- *
- * @author David Brownell
- * @version $Revision$
- */
-public class TreeWalker
-{
-    // yes, this is really a "TreeIterator" but the DOM WG plans to
-    // use such names in Level 2 ... so, we avoid it for now.  (note
-    // that they've also discussed a "TreeWalker" that's rather more
-    // complex than this iterator...)
-
-    private Node	startPoint;
-    private Node	current;
-
-    /**
-     * Constructs a tree walker starting at the given node.
-     */
-    public TreeWalker (Node initial)
-    {
-	if (initial == null) {
-	    throw new IllegalArgumentException (XmlDocument.catalog.
-				getMessage (Locale.getDefault (), "TW-004"));
-	}
-	if (!(initial instanceof NodeBase)) { 
-	    throw new IllegalArgumentException (XmlDocument.catalog.
-				getMessage (Locale.getDefault (), "TW-003"));
-	}
-	startPoint = current = initial;
-    }
-
-    /**
-     * Returns the current node.
-     */
-    public Node getCurrent ()
-    {
-	return current;
-    }
-
-    /**
-     * Advances to the next node, and makes that current.  Returns
-     * null if there are no more nodes through which to walk,
-     * because the initial node was reached or because a null
-     * parent was reached.
-     *
-     * @return the next node (which becomes current), or else null
-     */
-    public Node getNext ()
-    {
-	Node	next;
-
-	if (current == null)
-	    return null;
-
-	switch (current.getNodeType ()) {
-	  case Node.DOCUMENT_FRAGMENT_NODE:
-	  case Node.DOCUMENT_NODE:
-	  case Node.ELEMENT_NODE:
-	    //
-	    // For elements that can have children, visit those
-	    // children before any siblings (i.e. depth first)
-	    // and after visiting this node (i.e. preorder)
-	    //
-	    next = current.getFirstChild ();
-	    if (next != null) {
-		current = next;
-		return next;
-	    }
-	    // FALLTHROUGH
-
-	  case Node.ATTRIBUTE_NODE:
-	    // NOTE:  attributes "should" have children ...
-
-	  case Node.CDATA_SECTION_NODE:
-	  case Node.COMMENT_NODE:
-	  case Node.DOCUMENT_TYPE_NODE:
-	  case Node.ENTITY_REFERENCE_NODE:
-	  case Node.ENTITY_NODE:
-	  case Node.PROCESSING_INSTRUCTION_NODE:
-	  case Node.TEXT_NODE:
-	    //
-	    // For childless nodes, only look at siblings.  If no
-	    // siblings, climb the tree till we get to a spot there
-	    // are siblings, or till we terminate our walk.
-	    //
-	    for (Node here = current;
-		    here != null && here != startPoint;
-		    here = here.getParentNode ()) {
-		next = here.getNextSibling ();
-		if (next != null) {
-		    current = next;
-		    return next;
-		}
-	    }
-	    current = null;
-	    return null;
-	}
-	throw new InternalError (((NodeBase)startPoint).getMessage ("TW-000", 
-				new Object [] { Short.toString (current.
-					getNodeType ()) }));
-    }
-
-
-    /**
-     * Convenience method to walk only through elements with the specified
-     * tag name.  This just calls getNext() and filters out the nodes which
-     * aren't desired.  It returns null when the iteration completes.
-     *
-     * @param tag the tag to match, or null to indicate all elements
-     * @return the next matching element, or else null
-     */
-    public Element getNextElement (String tag)
-    {
-	for (Node next = getNext ();
-		next != null;
-		next = getNext ()) {
-	    if (next.getNodeType () == Node.ELEMENT_NODE
-		    && (tag == null || tag.equals (next.getNodeName ())))
-		return (Element) next;
-	}
-	current = null;
-	return null;
-    }
-
-    /**
-     * Namespace version
-     */
-    public Element getNextElement(String nsURI, String tag) {
-	for (Node next = getNext(); next != null; next = getNext()) {
-	    if (next.getNodeType () == Node.ELEMENT_NODE
-                && (nsURI == null || nsURI.equals(next.getNamespaceURI()))
-                && (tag == null || tag.equals(next.getNodeName()))) {
-		return (Element)next;
-            }
-	}
-	current = null;
-	return null;
-    }
-
-
-    /**
-     * Resets the walker to the state in which it was created:  the
-     * current node will be the node given to the constructor.  If
-     * the tree rooted at that node has been modified from the previous
-     * traversal, the sequence of nodes returned by <em>getNext()</em>
-     * will differ accordingly.
-     */
-    public void reset ()
-    {
-	current = startPoint;
-    }
-
-
-    /**
-     * Removes the current node; reassigns the current node to be the
-     * next one in the current walk that isn't a child of the (removed)
-     * current node, and returns that new current node.  In a loop, this
-     * could be used instead of a <em>getNext()</em>.
-     *
-     * @return the next node (which becomes current), or else null
-     * @throws IllegalStateException if the current node is null
-     *	or has no parent (it is a Document or DocumentFragment)
-     */
-    public Node removeCurrent ()
-    {
-	if (current == null)
-	    throw new IllegalStateException (((NodeBase)startPoint).
-						getMessage ("TW-001"));
-
-	Node	toRemove = current;
-	Node	parent = current.getParentNode ();
-	Node	retval = null;
-
-	if (parent == null)
-	    throw new IllegalStateException (((NodeBase)startPoint).
-	    					getMessage ("TW-002"));
-	
-	//
-	// Don't look at children, just siblings/parents
-	//
-	for (Node here = current;
-		here != null && here != startPoint;
-		here = here.getParentNode ()) {
-	    retval = here.getNextSibling ();
-	    if (retval != null) {
-		current = retval;
-		break;
-	    }
-	}
-	parent.removeChild (toRemove);
-	return retval;
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/XmlChars.java b/src/whiteboard/org/apache/xerces/tree/XmlChars.java
deleted file mode 100644
index 6548e57..0000000
--- a/src/whiteboard/org/apache/xerces/tree/XmlChars.java
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-
-/**
- * Methods in this class are used to determine whether characters may
- * appear in certain roles in XML documents.  Such methods are used
- * both to parse and to create such documents.
- *
- * @version 1.8
- * @author David Brownell
- */
-public class XmlChars
-{
-    // can't construct instances
-    private XmlChars () { }
-
-    /**
-     * Returns true if the argument, a UCS-4 character code, is valid in
-     * XML documents.  Unicode characters fit into the low sixteen
-     * bits of a UCS-4 character, and pairs of Unicode <em>surrogate
-     * characters</em> can be combined to encode UCS-4 characters in
-     * documents containing only Unicode.  (The <code>char</code> datatype
-     * in the Java Programming Language represents Unicode characters,
-     * including unpaired surrogates.)
-     *
-     * <P> In XML, UCS-4 characters can also be encoded by the use of
-     * <em>character references</em> such as <b>&amp;#x12345678;</b>, which
-     * happens to refer to a character that is disallowed in XML documents.
-     * UCS-4 characters allowed in XML documents can be expressed with
-     * one or two Unicode characters.
-     *
-     * @param ucs4char The 32-bit UCS-4 character being tested.
-     */
-    static public boolean isChar (int ucs4char)
-    {
-	// [2] Char ::= #x0009 | #x000A | #x000D
-	//			| [#x0020-#xD7FF]
-	//	... surrogates excluded!
-	//			| [#xE000-#xFFFD]
-	// 			| [#x10000-#x10ffff]
-	return ((ucs4char >= 0x0020 && ucs4char <= 0xD7FF)
-		|| ucs4char == 0x000A || ucs4char == 0x0009
-		|| ucs4char == 0x000D
-		|| (ucs4char >= 0xE000 && ucs4char <= 0xFFFD)
-		|| (ucs4char >= 0x10000 && ucs4char <= 0x10ffff));
-    }
-
-    /**
-     * Returns true if the character is allowed to be a non-initial
-     * character in names according to the XML recommendation.
-     * @see #isNCNameChar
-     * @see #isLetter
-     */
-    public static boolean isNameChar (char c)
-    {
-	// [4] NameChar ::= Letter | Digit | '.' | '_' | ':'
-	//			| CombiningChar | Extender
-
-	if (isLetter2 (c))
-	    return true;
-	else if (c == '>')
-	    return false;
-	else if (c == '.' || c == '-' || c == '_' || c == ':'
-		|| isExtender (c))
-	    return true;
-	else
-	    return false;
-    }
-
-    /**
-     * Returns true if the character is allowed to be a non-initial
-     * character in unscoped names according to the rules of the XML
-     * Namespaces proposed recommendation.  Except for precluding
-     * the colon (used to separate names from their scopes) these
-     * characters are just as allowed by the XML recommendation.
-     * @see #isNameChar
-     * @see #isLetter
-     */
-    public static boolean isNCNameChar (char c)
-    {
-	// [NC 5] NCNameChar ::= Letter | Digit | '.' | '_' 
-	//			| CombiningChar | Extender
-	return c != ':' && isNameChar (c);
-    }
-
-    /**
-     * Returns true if the character is allowed where XML supports
-     * whitespace characters, false otherwise.
-     */
-    public static boolean isSpace (char c)
-    {
-	return c == ' ' || c == '\t' || c == '\n' || c == '\r';
-    }
-
-
-    /*
-     * NOTE:  java.lang.Character.getType() values are:
-     *
-     * UNASSIGNED                    = 0,
-     *
-     * UPPERCASE_LETTER            = 1,    // Lu
-     * LOWERCASE_LETTER            = 2,    // Ll
-     * TITLECASE_LETTER            = 3,    // Lt
-     * MODIFIER_LETTER             = 4,    // Lm
-     * OTHER_LETTER                = 5,    // Lo
-     * NON_SPACING_MARK            = 6,    // Mn
-     * ENCLOSING_MARK              = 7,    // Me
-     * COMBINING_SPACING_MARK      = 8,    // Mc
-     * DECIMAL_DIGIT_NUMBER        = 9,    // Nd
-     * LETTER_NUMBER               = 10,   // Nl
-     * OTHER_NUMBER                = 11,   // No
-     * SPACE_SEPARATOR             = 12,   // Zs
-     * LINE_SEPARATOR              = 13,   // Zl
-     * PARAGRAPH_SEPARATOR         = 14,   // Zp
-     * CONTROL                     = 15,   // Cc
-     * FORMAT                      = 16,   // Cf
-     *                         // 17 reserved for proposed Ci category
-     * PRIVATE_USE                 = 18,   // Co
-     * SURROGATE                   = 19,   // Cs
-     * DASH_PUNCTUATION            = 20,   // Pd
-     * START_PUNCTUATION           = 21,   // Ps
-     * END_PUNCTUATION             = 22,   // Pe
-     * CONNECTOR_PUNCTUATION       = 23,   // Pc
-     * OTHER_PUNCTUATION           = 24,   // Po
-     * MATH_SYMBOL                 = 25,   // Sm
-     * CURRENCY_SYMBOL             = 26,   // Sc
-     * MODIFIER_SYMBOL             = 27,   // Sk
-     * OTHER_SYMBOL                = 28;   // So
-     */
-
-    /**
-     * Returns true if the character is an XML "letter".  XML Names must
-     * start with Letters or a few other characters, but other characters
-     * in names must only satisfy the <em>isNameChar</em> predicate.
-     *
-     * @see #isNameChar
-     * @see #isNCNameChar
-     */
-    public static boolean isLetter (char c)
-    {
-	// [84] Letter ::= BaseChar | Ideographic
-	// [85] BaseChar ::= ... too much to repeat
-	// [86] Ideographic ::= ... too much to repeat
-
-	//
-	// Optimize the typical case.
-	//
-	if (c >= 'a' && c <= 'z')
-	    return true;
-	if (c == '/')
-	    return false;
-	if (c >= 'A' && c <= 'Z')
-	    return true;
-
-	//
-	// Since the tables are too ridiculous to use in code,
-	// we're using the footnotes here to drive this test.
-	//
-	switch (Character.getType (c)) {
-	    // app. B footnote says these are 'name start'
-	    // chars' ...
-	  case Character.LOWERCASE_LETTER:		// Ll
-	  case Character.UPPERCASE_LETTER:		// Lu
-	  case Character.OTHER_LETTER:			// Lo
-	  case Character.TITLECASE_LETTER:		// Lt
-	  case Character.LETTER_NUMBER:			// Nl
-
-	    // OK, here we just have some exceptions to check...
-	    return !isCompatibilityChar (c)
-		    // per "5.14 of Unicode", rule out some combiners
-		&& !(c >= 0x20dd && c <= 0x20e0);
-
-	  default:
-	    // check for some exceptions:  these are "alphabetic"
-	    return ((c >= 0x02bb && c <=  0x02c1)
-		    || c == 0x0559 || c == 0x06e5 || c == 0x06e6);
-	}
-    }
-
-    //
-    // XML 1.0 discourages "compatibility" characters in names; these
-    // were defined to permit passing through some information stored in
-    // older non-Unicode character sets.  These always have alternative
-    // representations in Unicode, e.g. using combining chars.
-    //
-    private static boolean isCompatibilityChar (char c)
-    {
-	// the numerous comparisions here seem unavoidable,
-	// but the switch can reduce the number which must
-	// actually be executed.
-
-	switch ((c >> 8) & 0x0ff) {
-	  case 0x00:
-	    // ISO Latin/1 has a few compatibility characters
-	    return c == 0x00aa || c == 0x00b5 || c == 0x00ba;
-
-	  case 0x01:
-	    // as do Latin Extended A and (parts of) B
-	    return (c >= 0x0132 && c <= 0x0133)
-		|| (c >= 0x013f && c <= 0x0140)
-		|| c == 0x0149
-		|| c == 0x017f
-		|| (c >= 0x01c4 && c <= 0x01cc)
-		|| (c >= 0x01f1 && c <= 0x01f3) ;
-
-	  case 0x02:
-		   // some spacing modifiers
-	    return (c >= 0x02b0 && c <= 0x02b8)
-		|| (c >= 0x02e0 && c <= 0x02e4);
-	  
-	  case 0x03:
-	    return c == 0x037a;			// Greek
-
-	  case 0x05:
-	    return c == 0x0587;			// Armenian
-
-	  case 0x0e:
-	    return c >= 0x0edc && c <= 0x0edd;	// Laotian
-
-	  case 0x11:
-	    // big chunks of Hangul Jamo are all "compatibility"
-	    return c == 0x1101
-		|| c == 0x1104
-		|| c == 0x1108
-		|| c == 0x110a
-		|| c == 0x110d
-		|| (c >= 0x1113 && c <= 0x113b)
-		|| c == 0x113d
-		|| c == 0x113f
-		|| (c >= 0x1141 && c <= 0x114b)
-		|| c == 0x114d
-		|| c == 0x114f
-		|| (c >= 0x1151 && c <= 0x1153)
-		|| (c >= 0x1156 && c <= 0x1158)
-		|| c == 0x1162
-		|| c == 0x1164
-		|| c == 0x1166
-		|| c == 0x1168
-		|| (c >= 0x116a && c <= 0x116c)
-		|| (c >= 0x116f && c <= 0x1171)
-		|| c == 0x1174
-		|| (c >= 0x1176 && c <= 0x119d)
-		|| (c >= 0x119f && c <= 0x11a2)
-		|| (c >= 0x11a9 && c <= 0x11aa)
-		|| (c >= 0x11ac && c <= 0x11ad)
-		|| (c >= 0x11b0 && c <= 0x11b6)
-		|| c == 0x11b9
-		|| c == 0x11bb
-		|| (c >= 0x11c3 && c <= 0x11ea)
-		|| (c >= 0x11ec && c <= 0x11ef)
-		|| (c >= 0x11f1 && c <= 0x11f8)
-		;
-
-	  case 0x20:
-	    return c == 0x207f;			// superscript
-
-	  case 0x21:
-	    return
-		// various letterlike symbols
-		   c == 0x2102
-		|| c == 0x2107
-		|| (c >= 0x210a && c <= 0x2113)
-		|| c == 0x2115
-		|| (c >= 0x2118 && c <= 0x211d)
-		|| c == 0x2124
-		|| c == 0x2128
-		|| (c >= 0x212c && c <= 0x212d)
-		|| (c >= 0x212f && c <= 0x2138)
-
-		    // most Roman numerals (less 1K, 5K, 10K)
-		|| (c >= 0x2160 && c <= 0x217f)
-		;
-
-	  case 0x30:
-	    // some Hiragana
-	    return c >= 0x309b && c <= 0x309c;
-
-	  case 0x31:
-	    // all Hangul Compatibility Jamo
-	    return c >= 0x3131 && c <= 0x318e;
-
-	  case 0xf9:
-	  case 0xfa:
-	  case 0xfb:
-	  case 0xfc:
-	  case 0xfd:
-	  case 0xfe:
-	  case 0xff:
-	    // the whole "compatibility" area is for that purpose!
-	    return true;
-	
-	  default:
-	    // most of Unicode isn't flagged as being for compatibility
-	    return false;
-	}
-    }
-
-    // guts of isNameChar/isNCNameChar
-    private static boolean isLetter2 (char c)
-    {
-	// [84] Letter ::= BaseChar | Ideographic
-	// [85] BaseChar ::= ... too much to repeat
-	// [86] Ideographic ::= ... too much to repeat
-	// [87] CombiningChar ::= ... too much to repeat
-
-	//
-	// Optimize the typical case.
-	//
-	if (c >= 'a' && c <= 'z')
-	    return true;
-	if (c == '>')
-	    return false;
-	if (c >= 'A' && c <= 'Z')
-	    return true;
-
-	//
-	// Since the tables are too ridiculous to use in code,
-	// we're using the footnotes here to drive this test.
-	//
-	switch (Character.getType (c)) {
-	    // app. B footnote says these are 'name start'
-	    // chars' ...
-	  case Character.LOWERCASE_LETTER:		// Ll
-	  case Character.UPPERCASE_LETTER:		// Lu
-	  case Character.OTHER_LETTER:			// Lo
-	  case Character.TITLECASE_LETTER:		// Lt
-	  case Character.LETTER_NUMBER:			// Nl
-	    // ... and these are name characters 'other
-	    // than name start characters'
-	  case Character.COMBINING_SPACING_MARK:	// Mc
-	  case Character.ENCLOSING_MARK:		// Me
-	  case Character.NON_SPACING_MARK:		// Mn
-	  case Character.MODIFIER_LETTER:		// Lm
-	  case Character.DECIMAL_DIGIT_NUMBER:		// Nd
-
-	    // OK, here we just have some exceptions to check...
-	    return !isCompatibilityChar (c)
-		    // per "5.14 of Unicode", rule out some combiners
-		&& !(c >= 0x20dd && c <= 0x20e0);
-
-	  default:
-		// added a character ...
-	    return c == 0x0387;
-	}
-    }
-
-    private static boolean isDigit (char c)
-    {
-	// [88] Digit ::= ... 
-
-	//
-	// java.lang.Character.isDigit is correct from the XML point
-	// of view except that it allows "fullwidth" digits.
-	//
-	return Character.isDigit (c)
-		&& ! ( (c >= 0xff10) && (c <= 0xff19));
-    }
-
-    private static boolean isExtender (char c)
-    {
-	// [89] Extender ::= ... 
-	return c == 0x00b7 || c == 0x02d0 || c == 0x02d1 || c == 0x0387
-		|| c == 0x0640 || c == 0x0e46 || c == 0x0ec6
-		|| c == 0x3005 || (c >= 0x3031 && c <= 0x3035)
-		|| (c >= 0x309d && c <= 0x309e)
-		|| (c >= 0x30fc && c <= 0x30fe)
-		;
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/XmlDocument.java b/src/whiteboard/org/apache/xerces/tree/XmlDocument.java
deleted file mode 100644
index 1bb2b93..0000000
--- a/src/whiteboard/org/apache/xerces/tree/XmlDocument.java
+++ /dev/null
@@ -1,1455 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.io.OutputStream;
-import java.io.Writer;
-import java.io.IOException;
-
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Locale;
-
-import org.w3c.dom.*;
-
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-import org.xml.sax.helpers.XMLReaderFactory;
-import org.xml.sax.XMLReader;
-
-import org.apache.xerces.parsers.SAXParser;
-import org.apache.xerces.tree.Resolver;
-
-import org.apache.xerces.tree.MessageCatalog;
-import org.apache.xerces.tree.XmlNames;
-
-
-/**
- * This class implements the DOM <em>Document</em> interface, and also
- * provides static factory methods to create document instances.  Instances
- * represent the top level of an XML 1.0 document, typically consisting
- * of processing instructions followed by one tree of XML data.  These
- * documents may be written out for transfer or storage using a variety
- * of text encodings.
- *
- * <P> The static factory methods do not offer any customization options.
- * in particular, they do not enforce XML Namespaces when parsing, do not
- * offer customizable element factories, and discard certain information
- * which is not intended to be significant to applications.  If your
- * application requires more sophisticated use of DOM, you may need
- * to use SAX directly with an <em>XmlDocumentBuilder</em>.
- *
- * <P> Instances are factories for their subsidiary nodes, but applications
- * may provide their own element factory to bind element tags to particular
- * DOM implementation classes (which must subclass ElementNode).  For
- * example, a factory may use a set of classes which support the HTML DOM
- * methods, or which support methods associated with XML vocabularies for
- * specialized problem domains as found within Internet Commerce systems.
- * For example, an element tag <code>&lt;PurchaseOrder&gt;</code>
- * could be mapped to a <code>com.startup.commerce.PurchaseOrder</code>
- * class.  The factory can also use XML Namespace information, if desired.
- *
- * <P> Since DOM requires nodes to be owned exclusively by one document,
- * they can't be moved from one document to another using DOM APIs.  This
- * class provides an <em>changeNodeOwner</em> functionality which may be
- * used to change the document associated with a node, and with any of its
- * children.
- *
- * <P> <em> Only the core DOM model is supported here, not the HTML support.
- * Such support basically adds a set of convenience element types, and so
- * can be implemented through element factories and document subclasses.</em>
- *
- * @see XmlDocumentBuilder
- *
- * @author David Brownell
- * @author Rajiv Mordani
- * @version $Revision$
- */
-public class XmlDocument extends ParentNode
-    implements DocumentEx, DOMImplementation
-{
-    // package private (with jdk 1.1 'javac' bug workaround)
-    static /* final */ String		eol;
-
-    static {
-	String	temp;
-	try { temp = System.getProperty ("line.separator", "\n"); }
-	catch (SecurityException e) { temp = "\n"; }
-	eol = temp;
-    }
-
-    static final MessageCatalog		catalog = new Catalog ();
-
-    private Locale		locale = Locale.getDefault ();
-
-    private String		systemId;
-    private ElementFactory	factory;
-
-    // package private
-    int				mutationCount;
-    boolean replaceRootElement;
-
-    /** Constructs an empty document object. */
-    public XmlDocument ()
-    {
-    }
-
-    /**
-     * Construct an XML document from the data at the specified URI,
-     * optionally validating.  This uses validating parser if
-     * validation is requested, otherwise uses non-validating
-     * parser.  XML Namespace conformance is not tested when parsing.
-     *
-     * @param documentURI The URI (normally URL) of the document
-     * @param doValidate If true, validity errors are treated as fatal
-     *
-     * @exception IOException as appropriate
-     * @exception SAXException as appropriate
-     * @exception SAXParseException (with line number information)
-     *	for parsing errors
-     * @exception IllegalStateException at least when the parser
-     *	is configured incorrectly
-     */
-    public static XmlDocument createXmlDocument (
-	String	documentURI,
-	boolean	doValidate
-    ) throws IOException, SAXException
-    {
-	return createXmlDocument (new InputSource (documentURI), doValidate);
-    }
-
-
-    /**
-     * Construct an XML document from the data at the specified URI,
-     * using the nonvalidating parser.  XML Namespace conformance
-     * is not tested when parsing.
-     *
-     * @param documentURI The URI (normally URL) of the document
-     *
-     * @exception IOException as appropriate
-     * @exception SAXException as appropriate
-     * @exception SAXParseException (with line number information)
-     *	for parsing errors
-     * @exception IllegalStateException at least when the parser
-     *	is configured incorrectly
-     */
-    public static XmlDocument createXmlDocument (String documentURI)
-    throws IOException, SAXException
-    {
-	return createXmlDocument (new InputSource (documentURI), false);
-    }
-
-
-    /**
-     * Construct an XML document from input stream, optionally validating.
-     * This document must not require interpretation of relative URLs,
-     * since the base URL is not known.  This uses the validating parser
-     * if validation is requested, otherwise uses the non-validating
-     * parser.  XML Namespace conformance is not tested when parsing.
-     *
-     * @param in Holds xml document
-     * @param doValidate If true, validity errors are treated as fatal
-     *
-     * @exception IOException as appropriate
-     * @exception SAXException as appropriate
-     * @exception SAXParseException (with line number information)
-     *	for parsing errors
-     * @exception IllegalStateException at least when the parser
-     *	is configured incorrectly
-     */
-    public static XmlDocument createXmlDocument (
-	InputStream	in,
-	boolean		doValidate
-    ) throws IOException, SAXException
-    {
-	return createXmlDocument (new InputSource (in), doValidate);
-    }
-
-
-    /**
-     * Construct an XML document from the data in the specified input
-     * source, optionally validating.  This uses the validating parser
-     * if validation is requested, otherwise uses the non-validating
-     * parser.  XML Namespace conformance is not tested when parsing.
-     *
-     * @param in The input source of the document
-     * @param doValidate If true, validity errors are treated as fatal
-     *
-     * @exception IOException as appropriate
-     * @exception SAXException as appropriate
-     * @exception SAXParseException (with line number information)
-     *	for parsing errors
-     * @exception IllegalStateException at least when the parser
-     *	is configured incorrectly
-     */
-    public static XmlDocument createXmlDocument(InputSource in, 
-    						boolean validate)
-        throws IOException, SAXException
-    {
-        //XMLReader xmlReader = XMLReaderFactory.createXMLReader();
-
-        XMLReader xmlReader = new SAXParser ();
-
-        String namespaces = "http://xml.org/sax/features/namespaces";
-        xmlReader.setFeature(namespaces, true);
-
-        String nsPrefixes = "http://xml.org/sax/features/namespace-prefixes";
-        xmlReader.setFeature(nsPrefixes, true);
-
-        // Validation
-	if (validate) {
-        	xmlReader.setFeature(
-			"http://xml.org/sax/features/validation", true);
-  	}
-
-        // XmlDocumentBuilder is a ContentHandler
-        XmlDocumentBuilder builder = new XmlDocumentBuilder();
-        builder.setDisableNamespaces(false);
-
-        // The main ContentHandler
-        xmlReader.setContentHandler(builder);
-          
-        // org.xml.sax.ext.LexicalHandler
-        String lexHandler = "http://xml.org/sax/properties/lexical-handler";
-        xmlReader.setProperty(lexHandler, builder);
-//         Object prop = xmlReader.getProperty(lexHandler);
-//         System.out.println("LexicalHandler=" + prop);
-
-        // org.xml.sax.ext.DeclHandler
-        String declHandler
-            = "http://xml.org/sax/properties/declaration-handler";
-        xmlReader.setProperty(declHandler, builder);
-//         prop = xmlReader.getProperty(declHandler);
-//         System.out.println("DeclHandler=" + prop);
-
-        // DTDHandler
-        xmlReader.setDTDHandler(builder);
-
-	xmlReader.setEntityResolver (new Resolver ());
-
-        // Parse the input
-        xmlReader.parse(in);
-	return builder.getDocument();
-    }
-
-
-
-
-    /*
-     * Returns the top level document element.
-     * This is a convenience function in the big picture;
-     * use the DOM version instead, at least for now.
-     */
-    // package private
-    ElementNode getDocument ()
-    {
-	// We ignore comments, PIs, whitespace, etc
-	// and return the first (only!) element.
-	for (int i = 0; true; i++) {
-	    Node n = item (i);
-	    if (n == null)
-		return null;
-	    if (n instanceof ElementNode)
-		return (ElementNode) n;
-	}
-    }
-
-    /**
-     * Returns the locale to be used for diagnostic messages.
-     */
-    public Locale	getLocale ()
-	{ return locale; }
-    
-    /**
-     * Assigns the locale to be used for diagnostic messages.
-     * Multi-language applications, such as web servers dealing with
-     * clients from different locales, need the ability to interact
-     * with clients in languages other than the server's default.
-     * When an XmlDocument is created, its locale is the default
-     * locale for the virtual machine.
-     *
-     * @see #chooseLocale
-     */
-    public void	setLocale (Locale locale)
-    {
-	if (locale == null)
-	    locale = Locale.getDefault ();
-	this.locale = locale;
-    }
-
-    /**
-     * Chooses a client locale to use for diagnostics, using the first
-     * language specified in the list that is supported by this DOM
-     * implementation.  That locale is then automatically assigned using <a
-     * href="#setLocale(java.util.Locale)">setLocale()</a>.  Such a list
-     * could be provided by a variety of user preference mechanisms,
-     * including the HTTP <em>Accept-Language</em> header field.
-     *
-     * @see org.apache.xerces.tree.MessageCatalog
-     *
-     * @param languages Array of language specifiers, ordered with the most
-     *	preferable one at the front.  For example, "en-ca" then "fr-ca",
-     *  followed by "zh_CN".  Both RFC 1766 and Java styles are supported.
-     * @return The chosen locale, or null.
-     */
-    public Locale chooseLocale (String languages [])
-    {
-	Locale	l = catalog.chooseLocale (languages);
-
-	if (l != null)
-	    setLocale (l);
-	return l;
-    }
-
-    
-    /**
-     * Writes the document in UTF-8 character encoding, as a well formed
-     * XML construct.
-     *
-     * @param out stream on which the document will be written 
-     */
-    public void write (OutputStream out) throws IOException
-    {
-	Writer	writer = new OutputStreamWriter (out, "UTF8");
-	write (writer, "UTF-8");
-    }
-
-    /**
-     * Writes the document as a well formed XML construct.  If the
-     * encoding can be determined from the writer, that is used in
-     * the document's XML declaration.  The encoding name may first
-     * be transformed from a Java-internal form to a standard one;
-     * for example, Java's "UTF8" is the standard "UTF-8".
-     *
-     * <P> <em>Use of UTF-8 (or UTF-16) OutputStreamWriters is strongly
-     * encouraged. </em>  All other encodings may lose critical data,
-     * since the standard Java output writers substitute characters
-     * such as the question mark for data which they can't encode in
-     * the current output encoding.  The IETF and other organizations
-     * strongly encourage the use of UTF-8; also, all XML processors
-     * are guaranteed to support it.
-     *
-     * @see #write(java.io.Writer,java.lang.String)
-     *
-     * @param out stream on which the document will be written 
-     */
-    public void write (Writer out) throws IOException
-    {
-	String	encoding = null;
-
-	if (out instanceof OutputStreamWriter)
-	    encoding = java2std (((OutputStreamWriter)out).getEncoding ());
-        write (out, encoding);
-    }
-
-
-    //
-    // Try some of the common conversions from Java's internal names
-    // (which must fit in class names) to standard ones understood by
-    // most other code.  We use the IETF's preferred names; case is
-    // supposed to be ignored, note.
-    //
-    // package private 
-    static String java2std (String encodingName)
-    {
-	if (encodingName == null)
-	    return null;
-
-	//
-	// ISO-8859-N is a common family of 8 bit encodings;
-	// N=1 is the eight bit subset of UNICODE, and there
-	// seem to be at least drafts for some N >10.
-	//
-	if (encodingName.startsWith ("ISO8859_"))	// JDK 1.2
-	    return "ISO-8859-" + encodingName.substring (8);
-	if (encodingName.startsWith ("8859_"))		// JDK 1.1
-	    return "ISO-8859-" + encodingName.substring (5);
-
-	// XXX seven bit encodings ISO-2022-* ...
-	// XXX EBCDIC encodings ... 
-
-	if ("ASCII7".equalsIgnoreCase (encodingName)
-		|| "ASCII".equalsIgnoreCase (encodingName))
-	    return "US-ASCII";
-	
-	//
-	// All XML parsers _must_ support UTF-8 and UTF-16.
-	// (UTF-16 ~= ISO-10646-UCS-2 plus surrogate pairs)
-	//
-	if ("UTF8".equalsIgnoreCase (encodingName))
-	    return "UTF-8";
-	if (encodingName.startsWith ("Unicode"))
-	    return "UTF-16";
-	
-	//
-	// Some common Japanese character sets.
-	//
-	if ("SJIS".equalsIgnoreCase (encodingName))
-	    return "Shift_JIS";
-	if ("JIS".equalsIgnoreCase (encodingName))
-	    return "ISO-2022-JP";
-	if ("EUCJIS".equalsIgnoreCase (encodingName))
-	    return "EUC-JP";
-
-	// else we can't really do anything
-	return encodingName;
-    }
-
-    
-    /**
-     * Writes the document in the specified encoding, and listing
-     * that encoding in the XML declaration.  The document will be
-     * well formed XML; at this time, it will not additionally be
-     * valid XML or standalone, since it includes no document type
-     * declaration.
-     *
-     * <P> Note that the document will by default be "pretty printed".
-     * Extra whitespace is added to indent children of elements according
-     * to their level of nesting, unless those elements have (or inherit)
-     * the <em>xml:space='preserve'</em> attribute value.  This space
-     * will be removed if, when the document is read back with DOM, a
-     * call to <em>ElementNode.normalize</em> is made.  To avoid this
-     * pretty printing, use a write context configured to disable it,
-     * or explicitly assign an <em>xml:space='preserve'</em> attribute to
-     * the root node of your document.
-     *
-     * <P> Also, if a SAX parser was used to construct this tree, data
-     * will have been discarded.  Most of that will be insignificant in
-     * terms of a "logical" view of document data:  comments, whitespace
-     * outside of the top level element, the exact content of the XML
-     * directive, and entity references were expanded.  However, <em>if a
-     * DOCTYPE declaration was provided, it was also discarded</em>.
-     * Such declarations will often be logically significant, due to the
-     * attribute value defaulting and normalization they can provide.
-     *
-     * <P> In general, DOM does not support "round tripping" data from
-     * XML to DOM and back without losing data about physical structures
-     * and DTD information.  "Logical structure" will be preserved.
-     *
-     * @see #setDoctype
-     * @see #writeXml
-     *
-     * @param out the writer to use when writing the document
-     * @param encoding the encoding name to use; this should be a
-     *	standard encoding name registered with the IANA (like "UTF-8")
-     *	not a Java-internal name (like "UTF8").
-     */
-    public void write (Writer out, String encoding)
-    throws IOException
-    {
-	//
-	// We put a pretty minimal declaration here, which is the
-	// best we can do given SAX input and DOM.  For the moment
-	// this precludes our generating "standalone" annotations.
-	//
-	out.write ("<?xml version=\"1.0\"");
-	if (encoding != null) {
-	    out.write (" encoding=\"");
-	    out.write (encoding);
-	    out.write ('\"');
-	}
-	out.write ("?>");
-	out.write (eol);
-	out.write (eol);
-
-	writeChildrenXml (createWriteContext (out, 0));
-	out.write (eol);
-	out.flush ();
-    }
-
-    /**
-     * Returns an XML write context set up not to pretty-print,
-     * and which knows about the entities defined for this document.
-     *
-     * @param out stream on which the document will be written 
-     */
-    public XmlWriteContext createWriteContext (Writer out)
-    {
-	return new ExtWriteContext (out);
-    }
-
-    /**
-     * Returns an XML write context which pretty-prints output starting
-     * at a specified indent level, and which knows about the entities
-     * defined for this document.
-     *
-     * @param out stream on which the document will be written 
-     * @param level initial indent level for pretty-printing
-     */
-    public XmlWriteContext createWriteContext (Writer out, int level)
-    {
-	return new ExtWriteContext (out, level);
-    }
-
-    /**
-     * Writes the document out using the specified context, using
-     * an encoding name derived from the stream in the context where
-     * that is possible.
-     *
-     * @see #createWriteContext(java.io.Writer)
-     * @see #createWriteContext(java.io.Writer,int)
-     *
-     * @param context describes how to write the document
-     */
-    public void writeXml (XmlWriteContext context) throws IOException
-    {
-	Writer	out = context.getWriter ();
-	String	encoding = null;
-
-	//
-	// XXX as above, it should be possible to be "told" this name
-	// in order to use more standard names.  We can pretty print,
-	// or we can use the right encoding name; not both!!
-	//
-	if (out instanceof OutputStreamWriter)
-	    encoding = java2std (((OutputStreamWriter)out).getEncoding ());
-
-	//
-	// We put a pretty minimal declaration here, which is the
-	// best we can do given SAX input and DOM.  For the moment
-	// this precludes our generating "standalone" annotations.
-	//
-	out.write ("<?xml version=\"1.0\"");
-	if (encoding != null) {
-	    out.write (" encoding=\"");
-	    out.write (encoding);
-	    out.write ('\"');
-	}
-	out.write ("?>");
-	out.write (eol);
-	out.write (eol);
-
-	writeChildrenXml (context);
-    }
-
-    /**
-     * Writes all the child nodes of the document, following each one
-     * with the end-of-line string in use in this environment.
-     */
-    public void writeChildrenXml (XmlWriteContext context) throws IOException
-    {
-	int	length = getLength ();
-	Writer	out = context.getWriter ();
-
-	if (length == 0)
-	    return;
-	for (int i = 0; i < length; i++) {
-	    ((NodeBase)item (i)).writeXml (context);
-	    out.write (eol);
-	}
-    }
-
-
-    // package private -- overrides base class method
-    void checkChildType (int type)
-    throws DOMException
-    {
-	switch (type) {
-	  case ELEMENT_NODE:
-	  case PROCESSING_INSTRUCTION_NODE:
-	  case COMMENT_NODE:
-	  case DOCUMENT_TYPE_NODE:
-	    return;
-	  default:
-	    throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	}
-    }
-
-    /**
-     * Assigns the URI associated with the document, which is its
-     * system ID.
-     *
-     * @param uri The document's system ID, as used when storing
-     *	the document.
-     */
-    final public void setSystemId (String uri)
-    {
-	systemId = uri;
-    }
-
-    /**
-     * Returns system ID associated with the document, or null if
-     * this is unknown.
-     *
-     * <P> This URI should not be used when interpreting relative URIs,
-     * since the document may be partially stored in external parsed
-     * entities with different base URIs.  Instead, use methods in the
-     * <em>XmlReadable</em> interface as the document is being parsed,
-     * so that the correct base URI is available.
-     */
-    final public String getSystemId ()
-    {
-	return systemId;
-    }
-
-
-    // DOM support
-
-
-    /**
-     * DOM:  Appends the specified child node to the document.  Only one
-     * element or document type node may be a child of a document.
-     *
-     * @param node the node to be appended.
-     */
-    public Node appendChild (Node n)
-    throws DOMException
-    {
-	if (n instanceof Element && getDocument () != null)
-	    throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	if (n instanceof DocumentType && getDoctype () != null)
-	    throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	return super.appendChild (n);
-    }
-
-    /**
-     * DOM:  Inserts the specified child node into the document.  Only one
-     * element or document type node may be a child of a document.
-     *
-     * @param n the node to be inserted.
-     * @param refNode the node before which this is to be inserted
-     */
-    public Node insertBefore (Node n, Node refNode)
-    throws DOMException
-    {
-	if (!replaceRootElement && n instanceof Element && 
-	    getDocument () != null)
-	    throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	if (!replaceRootElement && n instanceof DocumentType 
-	    && getDoctype () != null)
-	    throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	return super.insertBefore (n, refNode);
-    }
-
-    /**
-     * <b>DOM:</b>  Replaces the specified child with the new node,
-     * returning the original child or throwing an exception.
-     * The new child must belong to this particular document.
-     *
-     * @param newChild the new child to be inserted
-     * @param refChild node which is to be replaced
-     */
-    public Node replaceChild (Node newChild, Node refChild)
-    throws DOMException
-    {
-    	if (newChild instanceof DocumentFragment ) {
-    	    int elemCount = 0;
-	    int docCount = 0;
-	    replaceRootElement = false;
-	    ParentNode frag = (ParentNode) newChild;
-	    Node temp;
-	    int i = 0;
-	    while ((temp = frag.item (i)) != null) {
-                if (temp instanceof Element) 
-    	            elemCount++;
-
-                 else if (temp instanceof DocumentType)
-	            docCount++;
-		i++;
-	    }
-	    if (elemCount > 1 || docCount > 1)
-	        throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	    else 
-	        replaceRootElement = true;
-	}
-	return super.replaceChild (newChild, refChild);
-    }
-
-
-    /** DOM: Returns the DOCUMENT_NODE node type constant. */
-    final public short getNodeType () { return DOCUMENT_NODE; }
-
-
-    /** DOM: returns the document type (DTD) */
-    final public DocumentType getDoctype ()
-    {
-	// We ignore comments, PIs, whitespace, etc
-	// and return the first (only!) doctype.
-	for (int i = 0; true; i++) {
-	    Node n = item (i);
-	    if (n == null)
-		return null;
-	    if (n instanceof DocumentType)
-		return (DocumentType) n;
-	}
-    }
-
-    // package private!!
-    Doctype createDoctype (String name)
-    {
-	Doctype	retval = new Doctype (name);
-	retval.setOwnerDocument (this);
-	return retval;
-    }
-
-    /**
-     * Establishes how the document prints its document type.  If a system
-     * ID (URI) is provided, that is used in a SYSTEM (or PUBLIC, if a public
-     * ID is also provided) declaration.  If an internal subset is provided,
-     * that will be printed.  The root element in the DTD will be what the
-     * document itself provides.
-     *
-     * @param dtdPublicId Holds a "public identifier" used to identify the
-     *	last part of the external DTD subset that is read into the DTD.
-     *	This may be omitted, and in any case is ignored unless a system
-     *	ID is provided.
-     * @param dtdSystemId Holds a "system identifier" (a URI) used to
-     *	identify the last part of the external DTD subset that is read
-     *	into the DTD.  This may be omitted, in which case the document
-     *	type will contain at most an internal subset.  This URI should
-     *	not be a relative URI unless the document will be accessed in a
-     *	context from which that relative URI makes sense.
-     * @param internalSubset Optional; this holds XML text which will
-     *	be put into the internal subset.  This must be legal syntax,
-     *	and it is not tested by this document.
-     */
-    public DocumentType setDoctype (
-	String	dtdPublicId,
-	String	dtdSystemId,
-	String	internalSubset
-    ) {
-	Doctype	retval = (Doctype) getDoctype ();
-
-	if (retval != null)
-	    retval.setPrintInfo (dtdPublicId, dtdSystemId,
-		    internalSubset);
-	else {
-	    retval = new Doctype (dtdPublicId, dtdSystemId,
-		    internalSubset);
-	    retval.setOwnerDocument (this);
-	    insertBefore (retval, getFirstChild ());
-	}
-	return retval;
-    }
-
-    
-    /** DOM: Returns the content root element. */
-    public Element getDocumentElement ()
-	{ return getDocument (); }
-
-    /**
-     * Assigns the element factory to be used by this document.
-     *
-     * @param factory the element factory to be used; if this is null,
-     *	all elements will be implemented by <em>ElementNode</em>.
-     */
-    final public void setElementFactory (ElementFactory factory)
-    {
-	this.factory = factory;
-    }
-
-    /**
-     * Returns the element factory to be used by this document.
-     */
-    final public ElementFactory getElementFactory ()
-    {
-	return factory;
-    }
-
-
-    /**
-     * DOM:  Create a new element, associated with this document, with
-     * no children, attributes, or parent, by calling createElementEx.
-     *
-     * @param tagName the tag of the element, used to determine what
-     *	type element to create as well as what tag to assign the new node.
-     * @exception IllegalArgumentException if a mapping is defined,
-     *	but is invalid because the element can't be instantiated or
-     *	does not subclass <em>ElementNode</em>.
-     */
-    final public Element createElement (String tagName)
-    throws DOMException
-    {
-	return createElementEx (tagName);
-    }
-
-    /**
-     * <b>DOM2:</b>
-     * @since DOM Level 2
-     * XXX Does not work with ElementFactory
-     */
-    public Element createElementNS(String namespaceURI, String qualifiedName)
-        throws DOMException
-    {
-        ElementNode retval = new ElementNode(namespaceURI, qualifiedName);
-	retval.setOwnerDocument(this);
-        return retval;
-    }
-
-    /**
-     * Create a new element, associated with this document, with no
-     * children, attributes, or parent.  This uses the element factory,
-     * or else directly constructs an ElementNode.
-     *
-     * @param tagName the tag of the element, used to determine what
-     *	type element to create as well as what tag to assign the new node.
-     * @exception IllegalArgumentException if a mapping is defined,
-     *	but is invalid because the element can't be instantiated or
-     *	does not subclass <em>ElementNode</em>.
-     */
-    final public ElementEx createElementEx (String tagName)
-    throws DOMException
-    {
-        ElementNode			retval;
-	
-	if (!XmlNames.isName (tagName))
-	    throw new DomEx (DomEx.INVALID_CHARACTER_ERR);
-
-	if (factory != null)
-	    retval = (ElementNode) factory.createElementEx (tagName);
-	else 
-	    retval = new ElementNode ();
-        retval.setTag (tagName);
-	retval.setOwnerDocument (this);
-        return retval;
-    }
-
-    /**
-     * Create a new element, associated with this document, with no
-     * children, attributes, or parent.  This uses the element factory,
-     * or else directly constructs an ElementNode.
-     *
-     * @param uri The namespace used to determine what type of element to
-     *	create.  This is not stored with the element; the element must be
-     *	inserted into a DOM tree in a location where namespace declarations
-     *	cause its tag to be interpreted correctly.
-     * @param tagName The tag of the element, which should not contain
-     *	any namespace prefix.
-     * @exception IllegalArgumentException When a mapping is defined,
-     *	but is invalid because the element can't be instantiated or
-     *	does not subclass <em>ElementNode</em>.
-     */
-    final public ElementEx createElementEx (String uri, String tagName)
-    throws DOMException
-    {
-        ElementNode	retval;
-	
-	if (!XmlNames.isName (tagName))
-	    throw new DomEx (DomEx.INVALID_CHARACTER_ERR);
-
-	if (factory != null)
-	    retval = (ElementNode) factory.createElementEx (uri, tagName);
-	else 
-	    retval = new ElementNode ();
-        retval.setTag (tagName);
-	retval.setOwnerDocument (this);
-        return retval;
-    }
-
-    /**
-     * DOM:  returns a Text node initialized with the given text.
-     *
-     * @param text The contents of the text node being created, which
-     *	should never contain "<em>]]&gt;</em>".
-     */
-    public Text createTextNode (String text)
-    {
-        TextNode			retval;
-	
-	retval = new TextNode ();
-	retval.setOwnerDocument (this);
-	if (text != null)
-	    retval.setText (text.toCharArray ());
-	return retval;
-    }
-
-    /**
-     * DOM:  Returns a CDATA section initialized with the given text.
-     *
-     * @param text the text which the CDATA section will hold, which
-     *	should never contain "<em>]]&gt;</em>".
-     */
-    public CDATASection createCDATASection (String text)
-    {
-	CDataNode	retval = new CDataNode ();
-
-	if (text != null)
-	    retval.setText (text.toCharArray ());
-	retval.setOwnerDocument (this);
-	return retval;
-    }
-
-    // package private ... convenience rtn, reduced mallocation
-    TextNode newText (char buf [], int offset, int len)
-    throws SAXException
-    {
-	TextNode	retval = (TextNode) createTextNode (null);
-	char		data [] = new char [len];
-
-	System.arraycopy (buf, offset, data, 0, len);
-	retval.setText (data);
-        return retval;
-    }
-        
-
-    /**
-     * DOM:  Returns a Processing Instruction node for the specified
-     * processing target, with the given instructions.
-     *
-     * @param target the target of the processing instruction
-     * @param instructions the processing instruction, which should
-     *	never contain "<em>?&gt;</em>".
-     */
-    public ProcessingInstruction createProcessingInstruction (
-	String target,
-	String instructions
-    ) throws DOMException
-    {
-	if (!XmlNames.isName (target))
-	    throw new DomEx (DomEx.INVALID_CHARACTER_ERR);
-
-	PINode	retval = new PINode (target, instructions);
-	retval.setOwnerDocument (this);
-	return retval;
-    }
-
-
-    /**
-     * DOM:  Returns a valueless attribute node with no default value.
-     *
-     * @param name the name of the attribute.
-     */
-    public Attr createAttribute (String name)
-    throws DOMException
-    {
-	if (!XmlNames.isName (name))
-	    throw new DomEx (DomEx.INVALID_CHARACTER_ERR);
-
-	AttributeNode retval = new AttributeNode (name, null, true, null);
-	retval.setOwnerDocument (this);
-	return retval;
-    }
-
-    /**
-     * <b>DOM2:</b>
-     * @since DOM Level 2
-     */
-    public Attr createAttributeNS(String namespaceURI,
-                                  String qualifiedName)
-        throws DOMException
-    {
-        // XXX do some checking here
-
-	AttributeNode retval = new AttributeNode(qualifiedName, null, true,
-                                                 null);
-	retval.setOwnerDocument(this);
-	return retval;
-    }
-
-    /**
-     * DOM:  creates a comment node.
-     *
-     * @param data The characters which will be in the comment.
-     *	This should not include the "<em>--</em>" characters.
-     */
-    public Comment createComment (String data)
-    {
-	CommentNode retval = new CommentNode (data);
-	retval.setOwnerDocument (this);
-	return retval;
-    }
-
-
-    /** DOM:  returns null. */
-    public Document getOwnerDoc ()
-    {
-	return null;
-    }
-
-    /**
-     * DOM: Returns an object describing the features of the DOM implementation 
-     * used by this document:  it supports the XML 1.0 feature set.
-     */
-    public DOMImplementation getImplementation ()
-	{ return this; }
-
-    /**
-     * DOM:  Creates a new document fragment.
-     */
-    public DocumentFragment createDocumentFragment ()
-    {
-	DocFragNode	retval = new DocFragNode ();
-	retval.setOwnerDocument (this);
-	return retval;
-    }
-
-
-    /**
-     * DOM:  Creates an entity reference to the named entity.
-     * Note that the entity must already be defined in the document
-     * type, and that the name must be a legal entity name.
-     *
-     * @param name the name of the the parsed entity
-     */
-    public EntityReference createEntityReference (String name)
-    throws DOMException
-    {
-	if (!XmlNames.isName (name))
-	    throw new DomEx (DomEx.INVALID_CHARACTER_ERR);
-
-	EntityRefNode retval = new EntityRefNode (name);
-	retval.setOwnerDocument (this);
-	return retval;
-    }
-
-
-    /** DOM: Returns the string "#document". */
-    final public String getNodeName () { return "#document"; }
-
-
-    /**
-     * DOM: Returns a copy of this document.
-     *
-     * <P> <em>Note:</em> At this time, any element factory or document
-     * type associated with this document will not be cloned.
-     *
-     * @param deep if true, child nodes are also cloned.
-     */
-    public Node cloneNode (boolean deep)
-    {
-	XmlDocument	retval = new XmlDocument ();
-
-	retval.systemId = systemId;
-	// XXX clone the element factory ...
-
-	if (deep) {
-	    Node	node;
-
-	    for (int i = 0; (node = item (i)) != null; i++) {
-		if (node instanceof DocumentType) {
-		    // XXX recreate
-		    continue;
-		}
-		node = node.cloneNode (true);
-		retval.changeNodeOwner (node);
-		retval.appendChild (node);
-	    }
-	}
-
-	return retval;
-    }
-
-    
-    /**
-     * Changes the "owner document" of the given node, and all child
-     * and associated attribute nodes, to be this document.  If the
-     * node has a parent, it is first removed from that parent.
-     * 
-     * @param node
-     * @exception DOMException WRONG_DOCUMENT_ERROR when attempting
-     *	to change the owner for some other DOM implementation<P>
-     *	HIERARCHY_REQUEST_ERROR when the node is a document, document
-     *	type, entity, or notation; or when it is an attribute associated
-     *  with an element whose owner is not being (recursively) changed.
-     */
-    final public void changeNodeOwner (Node node)
-    throws DOMException
-    {
-	TreeWalker	walker;
-	NodeBase	n;
-
-	if (node.getOwnerDocument () == this)
-	    return;
-	if (!(node instanceof NodeBase))
-	    throw new DomEx (DomEx.WRONG_DOCUMENT_ERR);
-
-	switch (node.getNodeType ()) {
-	  // Documents _are_ owners; can't switch identities
-	  case Node.DOCUMENT_NODE:
-
-	  // Entities, Notations only live in doctypes ... we
-	  // don't support changing their ownership at this time
-	  case Node.ENTITY_NODE:
-	  case Node.NOTATION_NODE:
-	  case Node.DOCUMENT_TYPE_NODE:
-	    throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	}
-
-	//
-	// If node is an attribute, its "scoped" by one element...
-	// and if that scope hasn't been changed (i.e. if this isn't
-	// a recursive call) we can't really fix anything!
-	//
-	if (node instanceof AttributeNode) {
-	    AttributeNode	attr = (AttributeNode) node;
-	    ElementNode		scope = attr.getNameScope ();
-
-	    if (scope != null && scope.getOwnerDocument () != this)
-		throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	}
-
-	// unparent node if needed
-	n = (NodeBase) node.getParentNode ();
-	if (n != null)
-	    n.removeChild (node);
-	
-	// change any children (including self)
-	for (walker = new TreeWalker (node),
-		    n = (NodeBase) walker.getCurrent ();
-		n != null;
-		n = (NodeBase) walker.getNext ()) {
-	    n.setOwnerDocument (this);
-
-	    // Elements have associated attributes, which must
-	    // also have owners changed.
-	    if (n instanceof ElementNode) {
-		NamedNodeMap	list = n.getAttributes ();
-		int		length = list.getLength ();
-		for (int i = 0; i < length; i++)
-		    changeNodeOwner (list.item (i));
-	    }
-	}
-    }
-
-    /**
-     * Reports on features that this implementation supports.  Allows code to
-     * be shared with NodeBase.supports().
-     */
-    static boolean hasFeature0(String feature, String version) {
-	if (!"XML".equalsIgnoreCase(feature)) {
-	    return false;
-        }
-        if (version.equalsIgnoreCase("2.0") || version.equalsIgnoreCase("1.0")
-                || version == null) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * DOM: Reports on features that this document supports
-     *
-     * @param feature identifies a feature of this DOM implementation;
-     *	case is ignored
-     * @param version optionally identifies the version of the feature
-     */
-    public boolean hasFeature(String feature, String version) {
-        return hasFeature0(feature, version);
-    }
-
-    /**
-     * <b>DOM2:</b>
-     * @since DOM Level 2
-     */
-    public DocumentType createDocumentType(String qualifiedName,
-                                           String publicId,
-                                           String systemId,
-                                           String internalSubset)
-    {
-        return new Doctype(qualifiedName, publicId, systemId, internalSubset);
-    }
-
-    public DocumentType createDocumentType(String qualifiedName,
-                                           String publicId,
-                                           String systemId)
-    {
-        return createDocumentType (qualifiedName, publicId, systemId, null);
-    }
-
-    /**
-     * <b>DOM2:</b>
-     * @since DOM Level 2
-     */
-    public Document createDocument(String namespaceURI, 
-                                   String qualifiedName, 
-                                   DocumentType doctype)
-        throws DOMException
-    {
-        // Create document and append DocumentType to it
-        // Note: WRONG_DOCUMENT_ERR is checked by appendChild()
-        Document doc = new XmlDocument();
-        doc.appendChild(doctype);
-
-        // Create document element and append it
-        // Note: name exceptions are checked by createElementNS()
-        Element docElement = doc.createElementNS(namespaceURI, qualifiedName);
-        doc.appendChild(docElement);
-
-        return doc;
-    }
-
-    /**
-     * <b>DOM2:</b>
-     * @since DOM Level 2
-     */
-    public Element getElementById(String elementId) {
-        return getElementExById(elementId);
-    }
-
-    /**
-     * Returns the element whose ID is given by the parameter; or null
-     * if no such element exists.  This relies on elements to know the 
-     * name of their ID attribute, as will be currently be true only if
-     * the document has been parsed from XML text with a DTD using the
-     * <em>XmlDocumentBuilder</em> class, or if it has been constructed
-     * using specialized DOM implementation classes which know the name
-     * of their ID attribute.  (XML allows only one ID attribute per
-     * element, and different elements may use different names for their
-     * ID attributes.)
-     *
-     * <P> This may be used to implement internal IDREF linkage, as well
-     * as some kinds of <em>XPointer</em> linkage as used in current
-     * drafts of <em>XLink</em>.
-     *
-     * @param id The value of the ID attribute which will be matched
-     *	by any element which is returned. 
-     */
-    // Note:  HTML DOM has getElementById() with "Element" return type
-    public ElementEx getElementExById (String id)
-    {
-	if (id == null)
-	    throw new IllegalArgumentException (getMessage ("XD-000"));
-
-	TreeWalker	w = new TreeWalker (this);
-	ElementEx	element;
-
-	while ((element = (ElementEx) w.getNextElement (null)) != null) {
-	    String	idAttr = element.getIdAttributeName ();
-	    String	value;
-
-	    if (idAttr == null)
-		continue;
-	    value = element.getAttribute (idAttr);
-	    if (value.equals (id))
-		return element;
-	}
-	return null;
-    }
-
-    /**
-     * @since DOM Level 2
-     * XXX Fix to better conform to spec.  cloneNode() also needs to be fixed.
-     */
-    public Node importNode(Node importedNode, boolean deep)
-        throws DOMException
-    {
-        Node retval = null;
-
-        switch (importedNode.getNodeType()) {
-        case DOCUMENT_NODE:
-        case DOCUMENT_TYPE_NODE:
-            throw new DomEx(DomEx.NOT_SUPPORTED_ERR);
-        default:
-            retval = importedNode.cloneNode(deep);
-        }
-
-        ((NodeBase)retval).setOwnerDocument(this);
-        return retval;
-    }
-
-
-    //
-    // Represent document fragments other than the document itself.
-    // (This class is primarily motivated for use with editors.)
-    //
-    static final class DocFragNode extends ParentNode
-	implements DocumentFragment
-    {
-	// package private -- overrides base class method
-	void checkChildType (int type)
-	throws DOMException
-	{
-	    switch (type) {
-	      case ELEMENT_NODE:
-	      case PROCESSING_INSTRUCTION_NODE:
-	      case COMMENT_NODE:
-	      case TEXT_NODE:
-	      case CDATA_SECTION_NODE:
-	      case ENTITY_REFERENCE_NODE:
-		return;
-	      default:
-		throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	    }
-	}
-
-	public void writeXml (XmlWriteContext context) throws IOException
-	{
-	    this.writeChildrenXml (context);
-	}
-
-	public Node getParentNode ()
-	    { return null; }
-	
-	public void setParentNode (Node p)
-	    { if (p != null) throw new IllegalArgumentException (); }
-	
-	public short getNodeType ()
-	    { return DOCUMENT_FRAGMENT_NODE; }
-	
-	public String getNodeName () { 
-	    return ("#document-fragment");
-	}
-	
-	public Node cloneNode (boolean deep)
-	{
-	    DocFragNode	retval = new DocFragNode ();
-	    ((NodeBase)retval).setOwnerDocument 
-	    			((XmlDocument)this.getOwnerDocument ());
-
-	    if (deep) {
-	        Node	node;
-
-	        for (int i = 0; (node = item (i)) != null; i++) {
-		    node = node.cloneNode (true);
-		    retval.appendChild (node);
-	        }
-	    }
-	    return retval;
-	}
-    }
-
-
-    //
-    // Represent entity references.
-    //
-    final static class EntityRefNode extends ParentNode
-	implements EntityReference
-    {
-	private String	entity;
-
-	EntityRefNode (String name)
-	{
-	    if (name == null)
-		throw new IllegalArgumentException (getMessage ("XD-002"));
-	    entity = name;
-	}
-	
-	// package private -- overrides base class method
-	void checkChildType (int type)
-	throws DOMException
-	{
-	    switch (type) {
-	      case ELEMENT_NODE:
-	      case PROCESSING_INSTRUCTION_NODE:
-	      case COMMENT_NODE:
-	      case TEXT_NODE:
-	      case CDATA_SECTION_NODE:
-	      case ENTITY_REFERENCE_NODE:
-		return;
-	      default:
-		throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
-	    }
-	}
-	public void writeXml (XmlWriteContext context)
-	throws IOException
-	{
-	    if (!context.isEntityDeclared (entity))
-		throw new IOException (getMessage ("XD-003", new Object[]
-							{ entity }));
-
-	    Writer out = context.getWriter ();
-
-	    out.write ('&');
-	    out.write (entity);
-	    out.write (';');
-	}
-
-	public short getNodeType ()
-	    { return ENTITY_REFERENCE_NODE; }
-	
-	public String getNodeName ()
-	    { return entity; }
-	
-	public Node cloneNode (boolean deep) { 
-	    EntityRefNode retval = new EntityRefNode (entity);
-	    ((NodeBase)retval).setOwnerDocument((
-	    			XmlDocument)this.getOwnerDocument ());
-	    if (deep) {
-	        Node	node;
-
-	        for (int i = 0; (node = item (i)) != null; i++) {
-		    node = node.cloneNode (true);
-		    retval.appendChild (node);
-	        }
-		// XXX
-		//throw new RuntimeException (getMessage ("XD-001"));
-	    }
-	    return retval;
-       	}
-    }
-
-    class ExtWriteContext extends XmlWriteContext
-    {
-	ExtWriteContext (Writer out) { super (out); }
-	ExtWriteContext (Writer out, int level) { super (out, level); }
-
-	public boolean isEntityDeclared (String name)
-	{
-	    if (super.isEntityDeclared (name))
-		return true;
-
-	    DocumentType	doctype = getDoctype ();
-
-	    if (doctype == null)
-		return false;
-	    else
-		return doctype.getEntities ().getNamedItem (name) != null;
-	}
-    }
-
-    static class Catalog extends MessageCatalog
-    {
-	Catalog () { super (Catalog.class); }
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/XmlDocumentBuilder.java b/src/whiteboard/org/apache/xerces/tree/XmlDocumentBuilder.java
deleted file mode 100644
index b1b1b2c..0000000
--- a/src/whiteboard/org/apache/xerces/tree/XmlDocumentBuilder.java
+++ /dev/null
@@ -1,1190 +0,0 @@
-/* 
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-
-import java.io.IOException;
-
-import java.net.URL;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.Locale;
-import java.util.Vector;
-
-import org.w3c.dom.CDATASection;
-import org.w3c.dom.Comment;
-import org.w3c.dom.Document;
-import org.w3c.dom.EntityReference;
-import org.w3c.dom.DOMException;
-
-import org.xml.sax.AttributeList;
-import org.xml.sax.DocumentHandler;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.DTDHandler;
-import org.xml.sax.XMLReader;
-import org.xml.sax.Attributes;
-import org.xml.sax.ext.LexicalHandler;
-import org.xml.sax.ext.DeclHandler;
-
-import org.apache.xerces.tree.AttributeListEx;
-import org.apache.xerces.tree.DtdEventListener;
-import org.apache.xerces.parsers.SAXParser;
-import org.apache.xerces.tree.Resolver;
-
-
-/**
- * This class is a SAX DocumentHandler which converts a stream of parse
- * events into an in-memory DOM document.  After each <em>Parser.parse()</em>
- * invocation returns, a resulting DOM Document may be accessed via the
- * <em>getDocument</em> method.  The parser and its builder should be used
- * together; the builder may be used with only one parser at a time.
- *
- * <P> This builder optionally does XML namespace processing, reporting
- * conformance problems as recoverable errors using the parser's error
- * handler.  
- *
- * <P> To customize the document, a powerful technique involves using
- * an element factory specifying what element tags (from a given XML
- * namespace) correspond to what implementation classes.  Parse trees
- * produced by such a builder can have nodes which add behaviors to
- * achieve application-specific functionality, such as modifing the tree
- * as it is parsed.
- *
- * <P> The object model here is that XML elements are polymorphic, with
- * semantic intelligence embedded through customized internal nodes.
- * Those nodes are created as the parse tree is built.  Such trees now
- * build on the W3C Document Object Model (DOM), and other models may be
- * supported by the customized nodes.  This allows both generic tools
- * (understanding generic interfaces such as the DOM core) and specialized
- * tools (supporting specialized behaviors, such as the HTML extensions
- * to the DOM core; or for XSL elements) to share data structures.
- *
- * <P> Normally only "model" semantics are in document data structures,
- * but "view" or "controller" semantics can be supported if desired.
- *
- * <P> Elements may choose to intercept certain parsing events directly.
- * They do this by overriding the default implementations of methods
- * in the <em>XmlReadable</em> interface.  This is normally done to make
- * the DOM tree represent application level modeling requirements, rather
- * than matching an XML structure that may not be optimized appropriately.
- *
- * @author David Brownell
- * @version $Revision$
- */
-public class XmlDocumentBuilder implements
-    ContentHandler, DocumentHandler, LexicalHandler, DTDHandler, DeclHandler
-{
-    // implicit predeclarations of "xml" namespace
-    private static final String
-	xmlURI = "http://www.w3.com/XML/1998/namespace";
-
-    // used during parsing
-    private XmlDocument		document;
-    private Locator		locator;
-    private ParseContextImpl	context = new ParseContextImpl ();
-    private Locale		locale = Locale.getDefault ();
-
-    private ElementFactory	factory;
-    private SAXParser		parser;
-    private Vector		attrTmp = new Vector ();
-    
-    private ParentNode		elementStack [];
-    private int         	topOfStack;
-    private boolean		inDTD;
-    private boolean		inCDataSection;
-
-    private Doctype		doctype;
-    private String		publicId;
-    private String		systemId;
-    private String		internalSubset;
-
-    // parser modes
-    private boolean		ignoringLexicalInfo = true;
-    private boolean		disableNamespaces = true;
-
-    
-    /**
-     * Default constructor is for use in conjunction with a SAX
-     * parser's <em>DocumentHandler</em> callback.
-     */
-    public XmlDocumentBuilder () { }
-
-    
-    /**
-     * Returns true (the default) if certain lexical information is
-     * automatically discarded when a DOM tree is built, producing
-     * smaller parse trees that are easier to use.
-     */
-    public boolean isIgnoringLexicalInfo () {
-	return ignoringLexicalInfo;
-    }
-
-    /**
-     * Controls whether certain lexical information is discarded; by
-     * default, that information is discarded.
-     *
-     * <P> That information includes whitespace in element content which
-     * is ignorable (note that some nonvalidating XML parsers will not
-     * report that information); all comments; which text is found in
-     * CDATA sections; and boundaries of entity references.
-     *
-     * <P> "Ignorable whitespace" as reported by parsers is whitespace
-     * used to format XML markup.  That is, all whitespace except that in
-     * "mixed" or ANY content models is ignorable.  When it is discarded,
-     * pretty-printing may be necessary to make the document be readable
-     * again by humans.
-     *
-     * <P> Whitespace inside "mixed" and ANY content models needs different
-     * treatment, since it could be part of the document content.  In such
-     * cases XML defines a <em>xml:space</em> attribute which applications
-     * should use to determine whether whitespace must be preserved (value
-     * of the attribute is <em>preserve</em>) or whether default behavior
-     * (such as eliminating leading and trailing space, and normalizing
-     * consecutive internal whitespace to a single space) is allowed.
-     *
-     * @param value true indicates that such lexical information should
-     *	be discarded during parsing.
-     */
-    public void setIgnoringLexicalInfo (boolean value) {
-	ignoringLexicalInfo = value;
-    }
-
-
-    /**
-     * Returns true if namespace conformance is not checked as the
-     * DOM tree is built.
-     */
-    public boolean getDisableNamespaces () {
-	return disableNamespaces;
-    }
-
-    /**
-     * Controls whether namespace conformance is checked during DOM
-     * tree construction, or (the default) not.  In this framework, the
-     * DOM Builder is responsible for enforcing all namespace constraints.
-     * When enabled, this makes constructing a DOM tree slightly slower.
-     * (However, at this time it can't enforce the requirement that
-     * parameter entity names not contain colons.)
-     */
-    public void setDisableNamespaces (boolean value) {
-	disableNamespaces = value;
-    }
-
-
-    /**
-     * Sets the parser used by this builder.  
-     */
-    public void setParser (org.xml.sax.Parser p)
-    {
-	p.setDocumentHandler (this);
-	if (p instanceof SAXParser) {
-	    parser = (SAXParser) p;
-	    parser.setDTDHandler (new DtdListener ());
-	} else
-	    parser = null;
-    }
-
-    /**
-     * Returns the parser used by this builder, if it is recorded.
-     */
-    public SAXParser getParser ()
-	{ return parser; }
-    
-    
-    /**
-     * Returns the fruits of parsing, after a SAX parser has used this
-     * as a document handler during parsing.
-     */
-    public XmlDocument getDocument () { return document; }
-    
-
-    /**
-     * Returns the locale to be used for diagnostic messages by
-     * this builder, and by documents it produces.  This uses
-     * the locale of any associated parser.
-     */
-    /*public Locale	getLocale ()
-    {
-	if (parser != null)
-	    return parser.getLocale ();
-	else
-	    return locale;
-    }*/
-    
-    /**
-     * Assigns the locale to be used for diagnostic messages.
-     * Multi-language applications, such as web servers dealing with
-     * clients from different locales, need the ability to interact
-     * with clients in languages other than the server's default.
-     *
-     * <P>When an XmlDocument is created, its locale is the default
-     * locale for the virtual machine.  If a parser was recorded,
-     * the locale will be associated with that parser.
-     *
-     * @see #chooseLocale
-     */
-    public void	setLocale (Locale locale)
-    throws SAXException
-    {
-	if (locale == null)
-	    locale = Locale.getDefault ();
-	if (parser != null)
-	    parser.setLocale (locale);
-	this.locale = locale;
-    }
-
-    /**
-     * Chooses a client locale to use for diagnostics, using the first
-     * language specified in the list that is supported by this builder.
-     * That locale is then automatically assigned using <a
-     * href="#setLocale(java.util.Locale)">setLocale()</a>.  Such a list
-     * could be provided by a variety of user preference mechanisms,
-     * including the HTTP <em>Accept-Language</em> header field.
-     *
-     * @see org.apache.xerces.tree.MessageCatalog
-     *
-     * @param languages Array of language specifiers, ordered with the most
-     *	preferable one at the front.  For example, "en-ca" then "fr-ca",
-     *  followed by "zh_CN".  Both RFC 1766 and Java styles are supported.
-     * @return The chosen locale, or null.
-     */
-    public Locale chooseLocale (String languages [])
-    throws SAXException
-    {
-	Locale	l = XmlDocument.catalog.chooseLocale (languages);
-
-	if (l != null)
-	    setLocale (l);
-	return l;
-    }
-
-    
-    // Document operations ...
-
-    /**
-     * <b>SAX</b> DocumentHandler callback, not for general application
-     * use.  Reports the locator object which will be used in reporting
-     * diagnostics and interpreting relative URIs in attributes and text.
-     *
-     * @param locator used to identify a location in an XML document
-     *	being parsed.
-     */
-    public void setDocumentLocator (Locator locator)
-    {
-	this.locator = locator;
-    }
-
-    /**
-     * Returns the document locator provided by the SAX parser.  This
-     * is commonly used in diagnostics, and when interpreting relative
-     * URIs found in XML Processing Instructions or other parts of an
-     * XML document.  This locator is only valid during document handler
-     * callbacks.
-     */
-    public Locator getDocumentLocator ()
-    {
-	return locator;
-    }
-    
-    
-    /**
-     * This is a factory method, used to create an XmlDocument.
-     * Subclasses may override this method, for example to provide
-     * document classes with particular behaviors, or provide
-     * particular factory behaviours (such as returning elements
-     * that support the HTML DOM methods, if they have the right
-     * name and are in the right namespace).
-     */
-    public XmlDocument createDocument ()
-    {
-	XmlDocument retval = new XmlDocument ();
-
-	if (factory != null)
-	    retval.setElementFactory (factory);
-	return retval;
-    }
-
-
-    /**
-     * Assigns the factory to be associated with documents produced
-     * by this builder.
-     */
-    final public void setElementFactory (ElementFactory factory)
-	{ this.factory = factory; }
-
-
-    /**
-     * Returns the factory to be associated with documents produced
-     * by this builder.
-     */
-    final public ElementFactory getElementFactory ()
-	{ return factory; }
-
-
-    /**
-     * <b>SAX</b> DocumentHandler callback, not for general application
-     * use.  Reports that the parser is beginning to process a document. 
-     */
-    public void startDocument () throws SAXException
-    {
-	document = createDocument ();
-
-	if (locator != null)
-	    document.setSystemId (locator.getSystemId ());
-
-	//
-        // XXX don't want fixed size limits!  Fix someday.  For
-	// now, wide trees predominate, not deep ones.  This is
-	// allowing a _very_ deep tree ... we typically observe
-	// depths on the order of a dozen.
-	//
-        elementStack = new ParentNode [200];
-        topOfStack = 0;
-        elementStack [topOfStack] = document;
-
-	inDTD = false;
-	document.startParse (context);
-    }
-
-    /**
-     * <b>SAX</b> DocumentHandler callback, not for general application
-     * use.  Reports that the document has been fully parsed.
-     */
-    public void endDocument () throws SAXException
-    {
-        if (topOfStack != 0)
-            throw new IllegalStateException (getMessage ("XDB-000"));
-	document.doneParse (context);
-	document.trimToSize ();
-    }
-    
-    private String getNamespaceURI (String prefix)
-    {
-	if ("xml".equals (prefix))
-	    return xmlURI;
-	else if ("xmlns".equals (prefix))
-	    return null;
-	else
-	    return elementStack [topOfStack]
-		    .getInheritedAttribute ("xmlns:" + prefix);
-    }
-    
-    /**
-     * <b>SAX</b> DocumentHandler callback, not for general application
-     * use.  Reports that the parser started to parse a new element,
-     * with the given tag and attributes, and call its <em>startParse</em>
-     * method.
-     *
-     * @exception SAXParseException if XML namespace support is enabled
-     *	and the tag or any attribute name contain more than one colon.
-     * @exception SAXException as appropriate, such as if a faulty parser
-     *	provides an element or attribute name which is illegal.
-     */
-    public void startElement (String tag, AttributeList attributes)
-    throws SAXException
-    {
-	AttributeSet		attrs = null;
-        ElementNode		e = null;
-	int			length;
-
-	//
-	// Convert set of attributes to DOM representation.
-	//
-	length = (attributes == null) ? 0 : attributes.getLength ();
-	if (length != 0) {
-	    try {
-		if (!disableNamespaces) {
-		    //
-		    // ID, IDREF(S), ENTITY(IES), NOTATION must be free of
-		    // colons in value ... only CDATA and NMTOKEN(S) excepted.
-		    //
-		    for (int i = 0; i < length; i++) {
-			String type = attributes.getType (i);
-			if ("CDATA".equals (type)
-				|| type.startsWith ("NMTOKEN"))
-			    continue;
-			if (attributes.getValue (i).indexOf (':') != -1)
-			    error (new SAXParseException ((getMessage
-			    	("XDB-001", new Object [] 
-					{ attributes.getName (i) })), locator));
-		    }
-		}
-		attrs = new AttributeSet (attributes);
-	    } catch (DOMException ex) {
-		fatal (new SAXParseException ((getMessage ("XDB-002", new
-				Object[] { ex.getMessage () })), locator, ex));
-	    }
-	}
-
-	//
-	// Then create the element, associate its attributes, and
-	// stack it for later addition.
-	//
-	try {
-	    if (disableNamespaces)
-		e = (ElementNode) document.createElementEx (tag);
-	    else {
-		int		index = tag.indexOf (':');
-		String		attribute = "xmlns";
-		String		namespace = "";
-		String		localPart = tag;
-
-		if (index != -1) {
-		    attribute = "xmlns:" + tag.substring (0, index);
-		    localPart = tag.substring (index + 1);
-		    if (tag.lastIndexOf (':') != index)
-			error (new SAXParseException ((getMessage ("XDB-003",
-				new Object [] { tag })), locator));
-		}
-
-		// Note: empty namespace URIs are ignored; the
-		// namespace spec doesn't say what they should do.
-		if (attrs != null)
-		    namespace = attrs.getValue (attribute);
-		if ("".equals (namespace))
-		    namespace = elementStack [topOfStack]
-			    .getInheritedAttribute (attribute);
-		e = (ElementNode) document.createElementEx (namespace,
-			localPart);
-
-		// remember whatever prefix it came with
-		if (localPart != tag)
-		    e.setTag (tag);
-	    }
-
-	} catch (DOMException ex) {
-	    fatal (new SAXParseException ((getMessage ("XDB-004", new
-	    		Object [] { ex.getMessage () })), locator, ex));
-	}
-	if (attributes != null && attributes instanceof AttributeListEx)
-	    e.setIdAttributeName (
-		((AttributeListEx)attributes).getIdAttributeName ());
-	if (length != 0)
-	    e.setAttributes (attrs);
-
-	elementStack [topOfStack++].appendChild (e);
-	elementStack [topOfStack] = e;
-	e.startParse (context);
-
-	//
-	// Division of responsibility for namespace processing is (being
-	// revised so) that the DOM builder reports errors when namespace
-	// constraints are violated, and the parser is ignorant of them.
-	//
-	if (!disableNamespaces) {
-	    int		index;
-	    String	prefix;
-
-	    // Element prefix must be declared
-	    index = tag.indexOf (':');
-	    if (index > 0) {
-		prefix = tag.substring (0, index);
-		if (getNamespaceURI (prefix) == null)
-		    error (new SAXParseException ((getMessage ("XDB-005",
-		    	new Object [] { prefix })), locator));
-	    }
-
-	    // Attribute prefixes must be declared, and only one instance
-	    // of a given attribute (scope + local part) may appear
-	    if (length != 0) {
-		// invariant:  attrTmp empty except in this block
-		for (int i = 0; i < length; i++) {
-		    String	name = attrs.item (i).getNodeName ();
-
-		    index = name.indexOf (':');
-		    if (index > 0) {
-			String	uri;
-
-			prefix = name.substring (0, index);
-			// "xmlns" is like a keyword
-			if ("xmlns".equals (prefix))
-			    continue;
-			uri = getNamespaceURI (prefix);
-			if (uri == null) {
-			    error (new SAXParseException ((getMessage
-			    	("XDB-006", new Object [] { prefix })),
-				locator));
-			    continue;
-			}
-			
-			if (name.lastIndexOf (':') != index)
-			    error (new SAXParseException ((getMessage
-			    	("XDB-007", new Object [] { name })), locator));
-
-			// Unicode ffff -- illegal in URIs and XML names;
-			// the value is otherwise irrelevant
-			name = name.substring (index + 1);
-			name = uri + '\uffff' + name;
-			if (attrTmp.contains (name))
-			    // duplicating attributes is a well-formedness
-			    // error, but we don't interpret violations of
-			    // namespace conformance as fatal errors if
-			    // we have a chance.
-			    error (new SAXParseException ((getMessage
-			    	("XDB-008", new Object [] { attrs.item
-				(i).getNodeName () })), locator));
-			else
-			    attrTmp.addElement (name);
-		    }
-		}
-		attrTmp.setSize (0);
-	    }
-	}
-    }
-    
-    public void startElement(String namespaceURI, String localName,
-                             String rawName, Attributes attributes)
-	throws SAXException
-    {
-	//
-	// Convert set of attributes to DOM representation.
-	//
-        AttributeSet attSet = null;
-	int length = attributes.getLength();
-	if (length != 0) {
-	    try {
-		attSet = new AttributeSet(attributes);
-	    } catch (DOMException ex) {
-		fatal (new SAXParseException ((getMessage ("XDB-002", new
-				Object[] { ex.getMessage () })), locator, ex));
-	    }
-	}
-
-	//
-	// Then create the element, associate its attributes, and
-	// stack it for later addition.
-	//
-        ElementNode e = null;
-	try {
-            if (namespaceURI.equals("")) {
-                // Translate "" of SAX2 to null.  See DOM2 spec under Node
-                // namespaceURI
-                namespaceURI = null;
-            }
-            e = (ElementNode)document.createElementNS(namespaceURI, rawName);
-	} catch (DOMException ex) {
-	    fatal (new SAXParseException ((getMessage ("XDB-004", new
-	    		Object [] { ex.getMessage () })), locator, ex));
-	}
-	if (attributes instanceof AttributeListEx) {
-	    e.setIdAttributeName(
-		((AttributeListEx)attributes).getIdAttributeName());
-        }
-	if (length != 0) {
-	    e.setAttributes(attSet);
-        }
-
-	elementStack[topOfStack++].appendChild(e);
-	elementStack[topOfStack] = e;
-	e.startParse(context);
-
-	//
-	// Division of responsibility for namespace processing is (being
-	// revised so) that the DOM builder reports errors when namespace
-	// constraints are violated, and the parser is ignorant of them.
-	//
-	if (!disableNamespaces) {
-            // XXX check duplicate attributes here ???
-	}
-    }
-
-    /**
-     * <b>SAX</b> DocumentHandler callback, not for general application
-     * use.  Reports that the parser finished the current element.
-     * The element's <em>doneParse</em> method is then called.
-     *
-     * @exception SAXException as appropriate
-     */
-    public void endElement (String tag)
-    throws SAXException
-    {
-        ElementNode e = (ElementNode) elementStack [topOfStack];
-
-        elementStack [topOfStack--] = null;
-
-	// Trusting that the SAX parser is correct, and hasn't
-	// mismatched start/end element callbacks.
-        // if (!tag.equals (e.getTagName ()))
-        //     fatal (new SAXParseException ((getMessage ("XDB-009", new
-	//         Object[] { tag, e.getTagName ()  })), locator));
-	try {
-	    e.doneParse (context);
-	    e.reduceWaste ();	// use less space
-	    elementStack [topOfStack].doneChild (e, context);
-
-	} catch (DOMException ex) {
-	    fatal (new SAXParseException ((getMessage ("XDB-004", new
-	    		Object [] { ex.getMessage () })), locator, ex));
-	}
-    }
-
-    public void endElement(String namespaceURI, String localName,
-                           String rawName)
-	throws SAXException
-    {
-        ElementNode e = (ElementNode) elementStack[topOfStack];
-
-        elementStack[topOfStack--] = null;
-
-	// Trusting that the SAX parser is correct, and hasn't
-	// mismatched start/end element callbacks.
-        // if (!tag.equals (e.getTagName ()))
-        //     fatal (new SAXParseException ((getMessage ("XDB-009", new
-	//         Object[] { tag, e.getTagName ()  })), locator));
-	try {
-	    e.doneParse(context);
-	    e.reduceWaste();	// use less space
-	    elementStack[topOfStack].doneChild(e, context);
-	} catch (DOMException ex) {
-	    fatal (new SAXParseException ((getMessage ("XDB-004", new
-	    		Object [] { ex.getMessage () })), locator, ex));
-	}
-    }
-
-    
-    /**
-     * LexicalEventListener callback, not for general application
-     * use.  Reports that CDATA section was begun.
-     *
-     * <P>If this builder is set to record lexical information (by default
-     * it ignores such information) then this callback arranges that
-     * character data (and ignorable whitespace) be recorded as part of
-     * a CDATA section, until the matching <em>endCDATA</em> method is
-     * called.
-     */
-    public void startCDATA () throws SAXException
-    {
-	if (ignoringLexicalInfo)
-	    return;
-
-        CDATASection	text = document.createCDATASection ("");
-        ParentNode	top = elementStack [topOfStack];
-        
-	try {
-	    inCDataSection = true;
-	    top.appendChild (text);
-	} catch (DOMException ex) {
-	    fatal (new SAXParseException ((getMessage ("XDB-004", new
-	    		Object [] { ex.getMessage () })), locator, ex));
-	}
-    }
-    
-    /**
-     * LexicalEventListener callback, not for general application
-     * use.  Reports that CDATA section was completed.
-     * This terminates any CDATA section that is being constructed.
-     */
-    public void endCDATA () throws SAXException
-    {
-	if (!inCDataSection)
-	    return;
-
-        ParentNode	top = elementStack [topOfStack];
-        
-	try {
-	    inCDataSection = false;
-	    top.doneChild ((NodeEx) top.getLastChild (), context);
-	} catch (DOMException ex) {
-	    fatal (new SAXParseException ((getMessage ("XDB-004", new
-	    		Object [] { ex.getMessage () })), locator, ex));
-	}
-    }
-    
-    /**
-     * <b>SAX</b> DocumentHandler callback, not for general application
-     * use.  Reports text which is part of the document, and which will
-     * be provided stored as a Text node.
-     *
-     * <P> Some parsers report "ignorable" whitespace through this interface,
-     * which can cause portability problems.  That's because there is no safe
-     * way to discard it from a parse tree without accessing DTD information,
-     * of a type which DOM doesn't expose and most applications won't want
-     * to deal with.  Avoid using such parsers.
-     *
-     * @param buf holds text characters
-     * @param offset initial index of characters in <em>buf</em>
-     * @param len how many characters are being passed
-     * @exception SAXException as appropriate
-     */
-    public void characters (char buf [], int offset, int len)
-    throws SAXException
-    {
-        ParentNode	top = elementStack [topOfStack];
-
-	if (inCDataSection) {
-	    String		temp = new String (buf, offset, len);
-	    CDATASection	section;
-
-	    section = (CDATASection) top.getLastChild ();
-	    section.appendData (temp);
-	    return;
-	}
-
-        
-	try {
-	    NodeBase lastChild = (NodeBase) top.getLastChild ();
-	    if (lastChild instanceof TextNode) {
-		String tmp  = new String (buf, offset, len);
-	   	((TextNode)lastChild).appendData (tmp);
-	    } else {
-        	TextNode text = document.newText (buf, offset, len);
-	        top.appendChild (text);
-	        top.doneChild (text, context);
-	    }
-	} catch (DOMException ex) {
-	    fatal (new SAXParseException ((getMessage ("XDB-004", new
-	    		Object [] { ex.getMessage () })), locator, ex));
-	}
-    }
-    
-    /**
-     * <b>SAX</b> DocumentHandler callback, not for general application
-     * use.  Reports ignorable whitespace; if lexical information is
-     * not ignored (by default, it is ignored) the whitespace reported
-     * here is recorded in a DOM text (or CDATA, as appropriate) node.
-     *
-     * @param buf holds text characters
-     * @param offset initial index of characters in <em>buf</em>
-     * @param len how many characters are being passed
-     * @exception SAXException as appropriate
-     */
-    public void ignorableWhitespace (char buf [], int offset, int len)
-    throws SAXException
-    {
-	if (ignoringLexicalInfo)
-	    return;
-
-        ParentNode	top = elementStack [topOfStack];
-
-	if (inCDataSection) {
-	    String		temp = new String (buf, offset, len);
-	    CDATASection	section;
-
-	    section = (CDATASection) top.getLastChild ();
-	    section.appendData (temp);
-	    return;
-	}
-
-        TextNode	text = document.newText (buf, offset, len);
-        
-	try {
-	    top.appendChild (text);
-	    top.doneChild (text, context);
-	} catch (DOMException ex) {
-	    fatal (new SAXParseException ((getMessage ("XDB-004", new
-	    		Object [] { ex.getMessage () })), locator, ex));
-	}
-    }
-    
-    /**
-     * <b>SAX</b> DocumentHandler callback, not for general application
-     * use.  Reports that a processing instruction was found.
-     *
-     * <P> Some applications may want to intercept processing instructions
-     * by overriding this method as one way to make such instructions
-     * take immediate effect during parsing, or to ensure that
-     * processing instructions in DTDs aren't ignored.
-     *
-     * @param name the processor to which the instruction is directed
-     * @param instruction the text of the instruction (no leading spaces)
-     * @exception SAXParseException if XML namespace support is enabled
-     *	and the name contains a colon.
-     * @exception SAXException as appropriate
-     */
-    public void processingInstruction (String name, String instruction) 
-    throws SAXException
-    {
-	if (!disableNamespaces && name.indexOf (':') != -1)
-	    error (new SAXParseException ((getMessage ("XDB-010")), locator));
-
-	// Ignore PIs in DTD for DOM support
-	if (inDTD)
-	    return;
-
-        ParentNode	top = elementStack [topOfStack];
-        PINode		pi;
-	
-	try {
-	    pi = (PINode) document.createProcessingInstruction (name,
-		    instruction);
-	    top.appendChild (pi);
-	    top.doneChild (pi, context);
-
-	} catch (DOMException ex) {
-	    fatal (new SAXParseException ((getMessage ("XDB-004", new
-	    		Object [] { ex.getMessage () })), locator, ex));
-	}
-    }
-
-    // mostly for namespace errors
-    private void error (SAXParseException err)
-    throws SAXException
-    {
-	if (parser != null)
-	    parser.getErrorHandler ().error (err);
-	else
-	    throw err;
-    }
-
-    private void fatal (SAXParseException err)
-    throws SAXException
-    {
-	if (parser != null)
-	    parser.getErrorHandler ().fatalError (err);
-	throw err;
-    }
-
-    class ParseContextImpl implements ParseContext
-    {
-	public ErrorHandler getErrorHandler ()
-	    { return (parser != null) ? parser.getErrorHandler () : null; }
-
-	public Locale getLocale () { 
-	    //return XmlDocumentBuilder.this.getLocale (); 
-	    // XXX need to change SAXParser for this
-	    return Locale.getDefault();
-	}
-
-	public Locator getLocator ()
-	    { return locator; }
-    }
-
-    //
-    // We really want to be able to use this ... not only does it
-    // build the DOM DocumentType object, but it also does many
-    // of the namespace conformance tests that SAX alone can't
-    // support.
-    //
-    class DtdListener implements DtdEventListener
-    {
-	private Doctype			doctype;
-	private String			publicId;
-	private String			systemId;
-	private String			internalSubset;
-
-	public void startDtd (String root)
-	{
-	    doctype = document.createDoctype (root);
-	    XmlDocumentBuilder.this.inDTD = true;
-	}
-
-	public void externalDtdDecl (String p, String s)
-	throws SAXException
-	{
-	    publicId = p;
-	    systemId = s;
-	}
-
-	public void internalDtdDecl (String s)
-	throws SAXException
-	{
-	    internalSubset = s;
-	}
-
-	public void externalEntityDecl (String n, String p, String s)
-	throws SAXException
-	{
-	    if (!disableNamespaces && n.indexOf (':') != -1)
-		error (new SAXParseException ((getMessage ("XDB-012")),
-		    locator));
-
-	    doctype.addEntityNode (n, p, s, null);
-	}
-
-	public void internalEntityDecl (String n, String v)
-	throws SAXException
-	{
-	    if (!disableNamespaces && n.indexOf (':') != -1)
-		error (new SAXParseException ((getMessage ("XDB-012")),
-		    locator));
-
-	    doctype.addEntityNode (n, v);
-	}
-
-	public void notationDecl (String n, String p, String s)
-	throws SAXException
-	{
-	    if (!disableNamespaces && n.indexOf (':') != -1)
-		error (new SAXParseException ((getMessage ("XDB-013")),
-		    locator));
-
-	    doctype.addNotation (n, p, s);
-	}
-
-	public void unparsedEntityDecl (String n, String p, String s, String t)
-	throws SAXException
-	{
-	    if (!disableNamespaces && n.indexOf (':') != -1)
-		error (new SAXParseException ((getMessage ("XDB-012")),
-		    locator));
-
-	    doctype.addEntityNode (n, p, s, t);
-	}
-
-	public void elementDecl (String elementName, String contentModel)
-	throws SAXException
-	{
-	    // ignored
-	}
-
-	public void attributeDecl (
-	    String		elementName,
-	    String		attributeName,
-	    String		attributeType,
-	    String		options [],
-	    String		defaultValue,
-	    boolean		isFixed,
-	    boolean		isRequired
-	) throws SAXException
-	{
-	    // ignored
-	}
-
-
-	public void endDtd ()
-	{
-	    doctype.setPrintInfo (publicId, systemId, internalSubset);
-	    document.appendChild (doctype);
-	    XmlDocumentBuilder.this.inDTD = false;
-	}
-    }
-
-    /*
-     * Gets the messages from the resource bundles for the given messageId.
-     */
-    String getMessage (String messageId) {
-   	return getMessage (messageId, null);
-    }
-
-    /*
-     * Gets the messages from the resource bundles for the given messageId
-     * after formatting it with the parameters passed to it.
-     */
-    String getMessage (String messageId, Object[] parameters) {
-   	/*if (locale == null) {
-		getLocale ();
-	}*/
-	return XmlDocument.catalog.getMessage (locale, messageId, parameters);
-    }
-
-
-    /*
-     * ContentHandler methods (some already declared above)
-     */
-
-    public void skippedEntity(String name) throws SAXException {
-    }
-
-    public void startPrefixMapping(String prefix, String uri)
-	throws SAXException
-    {
-    }
-
-    public void endPrefixMapping(String prefix)	throws SAXException {
-    }
-
-    /*
-     * org.xml.sax.ext.LexicalHandler methods (some already declared above)
-     */
-
-    public void startDTD(String name, String publicId, String systemId)
-	throws SAXException
-    {
-        doctype = document.createDoctype(name);
-        inDTD = true;
-	this.systemId = systemId;
-	this.publicId = publicId;
-    }
-
-    public void endDTD() throws SAXException {
-        doctype.setPrintInfo(publicId, systemId, internalSubset);
-        document.appendChild(doctype);
-        inDTD = false;
-    }
-
-    public void startEntity(String name) throws SAXException {
-    	// Our parser doesn't report Paramater entities. Need to make
-	// changes for that.
-
-        // Ignore entity refs while parsing DTD
-	if (ignoringLexicalInfo || inDTD) {
-	    return;
-        }
-
-        EntityReference	e = document.createEntityReference(name);
-	elementStack[topOfStack++].appendChild(e);
-	elementStack[topOfStack] = (ParentNode)e;
-    }
-
-    public void endEntity(String name) throws SAXException {
-        // Ignore entity refs while parsing DTD
-	if (inDTD) {
-            return;
-        }
-
-        ParentNode entity = elementStack[topOfStack];
-
-	if (!(entity instanceof EntityReference))
-	    return;
-
-	entity.setReadonly(true);
-        elementStack[topOfStack--] = null;
-        if (!name.equals(entity.getNodeName()))
-            fatal(new SAXParseException ((getMessage ("XDB-011", new
-                    Object[] { name, entity.getNodeName () })), locator));
-	try {
-	    elementStack[topOfStack].doneChild(entity, context);
-	} catch (DOMException ex) {
-	    fatal(new SAXParseException ((getMessage ("XDB-004", new
-                    Object [] { ex.getMessage () })), locator, ex));
-	}
-    }
-
-    // startCDATA() defined above
-
-    // endCDATA() defined above
-
-    public void comment(char[] ch, int start, int length) throws SAXException {
-	// Ignore comments if lexical info is to be ignored,
-	// or if parsing the DTD
-	if (ignoringLexicalInfo || inDTD) {
-	    return;
-        }
-
-        String text = new String(ch, start, length);
-        Comment comment = document.createComment(text);
-        ParentNode top = elementStack[topOfStack];
-        
-	try {
-	    top.appendChild(comment);
-	    top.doneChild((NodeEx) comment, context);
-	} catch (DOMException ex) {
-	    fatal(new SAXParseException((getMessage("XDB-004", new
-                    Object[] { ex.getMessage() })), locator, ex));
-	}
-    }
-
-
-    /*
-     * org.xml.sax.ext.DeclHandler methods
-     */
-
-    public void elementDecl(String name, String model) throws SAXException {
-        // ignored
-    }
-
-    public void attributeDecl(String eName, String aName, String type,
-                              String valueDefault, String value)
-	throws SAXException
-    {
-        // ignored
-    }
-
-    public void internalEntityDecl(String name, String value)
-	throws SAXException
-    {
-        if (!disableNamespaces && name.indexOf (':') != -1) {
-            error(new SAXParseException((getMessage("XDB-012")), locator));
-        }
-
-        doctype.addEntityNode(name, value);
-    }
-
-    public void externalEntityDecl(String name, String publicId,
-                                   String systemId)
-	throws SAXException
-    {
-        if (!disableNamespaces && name.indexOf (':') != -1) {
-            error(new SAXParseException((getMessage("XDB-012")), locator));
-        }
-
-        doctype.addEntityNode(name, publicId, systemId, null);
-    }
-
-    /*
-     * DTDHandler methods
-     */
-
-    public void notationDecl (String n, String p, String s)
-	throws SAXException
-    {
-        if (!disableNamespaces && n.indexOf (':') != -1)
-            error (new SAXParseException ((getMessage ("XDB-013")),
-                                          locator));
-
-        doctype.addNotation (n, p, s);
-    }
-
-    public void unparsedEntityDecl (String name, String publicId, 
-    				    String systemId, String notation)
-	throws SAXException
-    {
-        if (!disableNamespaces && name.indexOf (':') != -1)
-            error (new SAXParseException ((getMessage ("XDB-012")),
-                                          locator));
-
-        doctype.addEntityNode (name, publicId, systemId, notation);
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/XmlNames.java b/src/whiteboard/org/apache/xerces/tree/XmlNames.java
deleted file mode 100644
index b8ddee9..0000000
--- a/src/whiteboard/org/apache/xerces/tree/XmlNames.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-/**
- * This class contains static methods used to determine whether identifiers
- * may appear in certain roles in XML documents.  Such methods are used
- * both to parse and to create such documents.
- *
- * @version 1.4
- * @author David Brownell
- */
-public class XmlNames 
-{
-    private XmlNames () { }
-
-
-    /**
-     * Returns true if the value is a legal XML name.
-     *
-     * @param value the string being tested
-     */
-    public static boolean isName (String value)
-    {
-	if (value == null)
-	    return false;
-
-	char c = value.charAt (0);
-	if (!XmlChars.isLetter (c) && c != '_' && c != ':')
-	    return false;
-	for (int i = 1; i < value.length (); i++)
-	    if (!XmlChars.isNameChar (value.charAt (i)))
-		return false;
-	return true;
-    }
-
-    /**
-     * Returns true if the value is a legal "unqualified" XML name, as
-     * defined in the XML Namespaces proposed recommendation.
-     * These are normal XML names, except that they may not contain
-     * a "colon" character.
-     *
-     * @param value the string being tested
-     */
-    public static boolean isUnqualifiedName (String value)
-    {
-	if (value == null || value.length() == 0)
-	    return false;
-
-	char c = value.charAt (0);
-	if (!XmlChars.isLetter (c) && c != '_')
-	    return false;
-	for (int i = 1; i < value.length (); i++)
-	    if (!XmlChars.isNCNameChar (value.charAt (i)))
-		return false;
-	return true;
-    }
-
-    /**
-     * Returns true if the value is a legal "qualified" XML name, as defined
-     * in the XML Namespaces proposed recommendation.  Qualified names are
-     * composed of an optional prefix (an unqualified name), followed by a
-     * colon, and a required "local part" (an unqualified name).  Prefixes are
-     * declared, and correspond to particular URIs which scope the "local
-     * part" of the name.  (This method cannot check whether the prefix of a
-     * name has been declared.)
-     *
-     * @param value the string being tested
-     */
-    public static boolean isQualifiedName (String value)
-    {
-	if (value == null)
-	    return false;
-
-        // [6] QName ::= (Prefix ':')? LocalPart
-        // [7] Prefix ::= NCName
-        // [8] LocalPart ::= NCName
-
-	int	first = value.indexOf (':');
-
-        // no Prefix, only check LocalPart
-        if (first <= 0)
-            return isUnqualifiedName (value);
-
-        // Prefix exists, check everything
-
-	int	last = value.lastIndexOf (':');
-	if (last != first)
-	    return false;
-	
-	return isUnqualifiedName (value.substring (0, first))
-		&& isUnqualifiedName (value.substring (first + 1));
-    }
-
-    /**
-     * This method returns true if the identifier is a "name token"
-     * as defined in the XML specification.  Like names, these
-     * may only contain "name characters"; however, they do not need
-     * to have letters as their initial characters.  Attribute values
-     * defined to be of type NMTOKEN(S) must satisfy this predicate.
-     *
-     * @param token the string being tested
-     */
-    public static boolean isNmtoken (String token)
-    {
-	int	length = token.length ();
-
-	for (int i = 0; i < length; i++)
-	    if (!XmlChars.isNameChar (token.charAt (i)))
-		return false;
-	return true;
-    }
-
-
-    /**
-     * This method returns true if the identifier is a "name token" as
-     * defined by the XML Namespaces proposed recommendation.
-     * These are like XML "name tokens" but they may not contain the
-     * "colon" character.
-     *
-     * @see #isNmtoken
-     *
-     * @param token the string being tested
-     */
-    public static boolean isNCNmtoken (String token)
-    {
-	return isNmtoken (token) && token.indexOf (':') < 0;
-    }
-
-    /**
-     * Return the Prefix of qualifiedName.  Does not check that Prefix is a
-     * valid NCName.
-     *
-     * @param qualifiedName name to find the Prefix of
-     * @return prefix or null if it has none
-     */
-    public static String getPrefix(String qualifiedName) {
-        // [6] QName ::= (Prefix ':')? LocalPart
-        // [7] Prefix ::= NCName
-        int index = qualifiedName.indexOf(':');
-        return index <= 0 ? null : qualifiedName.substring(0, index);
-    }
-
-    /**
-     * Return the LocalPart of qualifiedName.  Does not check that Prefix is a
-     * valid NCName.
-     *
-     * @param qualifiedName name to find the LocalPart of
-     * @return LocalPart or null if it has none
-     */
-    public static String getLocalPart(String qualifiedName) {
-        // [6] QName ::= (Prefix ':')? LocalPart
-        // [8] LocalPart ::= NCName
-	int index = qualifiedName.indexOf(':');
-	if (index < 0) {
-	    return qualifiedName;
-        }
-
-        // ':' at end of qualifiedName
-        if (index == qualifiedName.length() - 1) {
-            return null;
-        }
-
-	return qualifiedName.substring(index + 1);
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/XmlReadable.java b/src/whiteboard/org/apache/xerces/tree/XmlReadable.java
deleted file mode 100644
index 6345083..0000000
--- a/src/whiteboard/org/apache/xerces/tree/XmlReadable.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import org.w3c.dom.*;
-import org.xml.sax.SAXException;
-
-
-/**
- * This interface is supported by XML documents and elements which wish to
- * interact with DOM construction during parsing of XML documents.  The
- * parse context which is provided allows elements to determine the URI of
- * the document in which they are found, for interpreting relative URIs.
- * It also supports providing application level diagnostics for faulty
- * input.
- *
- * <P> When these methods are called, parent context is available for
- * elements so that "inherited" attributes may be queried, as well as
- * other information such as the types of any containing elements.
- *
- * @author David Brownell
- * @version $Revision$
- */
-public interface XmlReadable
-{
-    /**
-     * This is called before object children are parsed.  For elements,
-     * this is a natural time to perform tasks which relate to element
-     * attributes, such as application level integrity checks or
-     * associating them with object properties.
-     */
-    void startParse (ParseContext context)
-    throws SAXException;
-
-    /**
-     * This is called when each child element has been 
-     * fully constructed.  The object may choose to represent the
-     * child's information in a manner which is more appropriate to a
-     * particular application, or even discard that information if it
-     * is not currently needed.  For example, this is a good time for
-     * elements discard ignorable whitespace, filter out elements not matching
-     * some search criteria, or map certain elements to object properties.
-     */
-    void doneChild (NodeEx newChild, ParseContext context)
-    throws SAXException;
-
-    /**
-     * This is called when the object has been fully parsed, sometime after
-     * startParse.  It is a natural time to perform tasks which relate to
-     * all children, such as verifying application level integrity constraints
-     * or associating an appropriate <em>userObject</em> with this element.
-     * Documents may wish to perform ID/IDREF link fixup, or similar tasks.
-     */
-    void doneParse (ParseContext context)
-    throws SAXException;
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/XmlReader.java b/src/whiteboard/org/apache/xerces/tree/XmlReader.java
deleted file mode 100644
index ad0d93f..0000000
--- a/src/whiteboard/org/apache/xerces/tree/XmlReader.java
+++ /dev/null
@@ -1,864 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import java.io.*;
-import java.util.Hashtable;
-
-
-// NOTE:  Add I18N support to this class when JDK gets the ability to
-// defer selection of locale for exception messages ... use the same
-// technique for both.
-
-
-/**
- * This handles several XML-related tasks that normal java.io Readers
- * don't support, inluding use of IETF standard encoding names and
- * automatic detection of most XML encodings.  The former is needed
- * for interoperability; the latter is needed to conform with the XML
- * spec.  This class also optimizes reading some common encodings by
- * providing low-overhead unsynchronized Reader support.
- *
- * <P> Note that the autodetection facility should be used only on
- * data streams which have an unknown character encoding.  For example,
- * it should never be used on MIME text/xml entities.
- *
- * <P> Note that XML processors are only required to support UTF-8 and
- * UTF-16 character encodings.  Autodetection permits the underlying Java
- * implementation to provide support for many other encodings, such as
- * US-ASCII, ISO-8859-5, Shift_JIS, EUC-JP, and ISO-2022-JP.
- *
- * @author David Brownell
- * @version $Revision$
- */
-// package private
-final class XmlReader extends Reader
-{
-    private static final int MAXPUSHBACK = 512;
-
-    private Reader	in;
-    private String	assignedEncoding;
-    private boolean	closed;
-
-    //
-    // This class always delegates I/O to a reader, which gets
-    // its data from the very beginning of the XML text.  It needs
-    // to use a pushback stream since (a) autodetection can read
-    // partial UTF-8 characters which need to be fully processed,
-    // (b) the "Unicode" readers swallow characters that they think
-    // are byte order marks, so tests fail if they don't see the
-    // real byte order mark.
-    //
-    // It's got do this efficiently:  character I/O is solidly on the
-    // critical path.  (So keep buffer length over 2 Kbytes to avoid
-    // excess buffering. Many URL handlers stuff a BufferedInputStream
-    // between here and the real data source, and larger buffers keep
-    // that from slowing you down.)
-    //
-
-    /**
-     * Constructs the reader from an input stream, autodetecting
-     * the encoding to use according to the heuristic specified
-     * in the XML 1.0 recommendation.
-     *
-     * @param in the input stream from which the reader is constructed
-     * @exception IOException on error, such as unrecognized encoding
-     */
-    public static Reader createReader (InputStream in) throws IOException
-    {
-	return new XmlReader (in);
-    }
-
-    /**
-     * Creates a reader supporting the given encoding, mapping
-     * from standard encoding names to ones that understood by
-     * Java where necessary.
-     *
-     * @param in the input stream from which the reader is constructed
-     * @param encoding the IETF standard name of the encoding to use;
-     *	if null, autodetection is used.
-     * @exception IOException on error, including unrecognized encoding
-     */
-    public static Reader createReader (InputStream in, String encoding)
-    throws IOException
-    {
-	if (encoding == null)
-	    return new XmlReader (in);
-	if ("UTF-8".equalsIgnoreCase (encoding)
-		|| "UTF8".equalsIgnoreCase (encoding))
-	    return new Utf8Reader (in);
-	if ("US-ASCII".equalsIgnoreCase (encoding)
-		|| "ASCII".equalsIgnoreCase (encoding))
-	    return new AsciiReader (in);
-	if ("ISO-8859-1".equalsIgnoreCase (encoding)
-		// plus numerous aliases ... 
-		)
-	    return new Iso8859_1Reader (in);
-
-	//
-	// What we really want is an administerable resource mapping
-	// encoding names/aliases to classnames.  For example a property
-	// file resource, "readers/mapping.props", holding and a set
-	// of readers in that (sub)package... defaulting to this call
-	// only if no better choice is available.
-	//
-	return new InputStreamReader (in, std2java (encoding));
-    }
-
-    //
-    // JDK doesn't know all of the standard encoding names, and
-    // in particular none of the EBCDIC ones IANA defines (and
-    // which IBM encourages).
-    //
-    static private final Hashtable charsets = new Hashtable (31);
-
-    static {
-	charsets.put ("UTF-16", "Unicode");
-	charsets.put ("ISO-10646-UCS-2", "Unicode");
-
-	// NOTE: no support for ISO-10646-UCS-4 yet.
-
-	charsets.put ("EBCDIC-CP-US", "cp037");
-	charsets.put ("EBCDIC-CP-CA", "cp037");
-	charsets.put ("EBCDIC-CP-NL", "cp037");
-	charsets.put ("EBCDIC-CP-WT", "cp037");
-
-	charsets.put ("EBCDIC-CP-DK", "cp277");
-	charsets.put ("EBCDIC-CP-NO", "cp277");
-	charsets.put ("EBCDIC-CP-FI", "cp278");
-	charsets.put ("EBCDIC-CP-SE", "cp278");
-
-	charsets.put ("EBCDIC-CP-IT", "cp280");
-	charsets.put ("EBCDIC-CP-ES", "cp284");
-	charsets.put ("EBCDIC-CP-GB", "cp285");
-	charsets.put ("EBCDIC-CP-FR", "cp297");
-
-	charsets.put ("EBCDIC-CP-AR1", "cp420");
-	charsets.put ("EBCDIC-CP-HE", "cp424");
-	charsets.put ("EBCDIC-CP-BE", "cp500");
-	charsets.put ("EBCDIC-CP-CH", "cp500");
-
-	charsets.put ("EBCDIC-CP-ROECE", "cp870");
-	charsets.put ("EBCDIC-CP-YU", "cp870");
-	charsets.put ("EBCDIC-CP-IS", "cp871");
-	charsets.put ("EBCDIC-CP-AR2", "cp918");
-
-	// IANA also defines two that JDK 1.2 doesn't handle:
-	//	EBCDIC-CP-GR		--> CP423
-	//	EBCDIC-CP-TR		--> CP905
-    }
-
-    // returns an encoding name supported by JDK >= 1.1.6
-    // for some cases required by the XML spec
-    private static String std2java (String encoding)
-    {
-	String temp = encoding.toUpperCase ();
-	temp = (String) charsets.get (temp);
-	return temp != null ? temp : encoding;
-    }
-
-    /** Returns the standard name of the encoding in use */
-    public String getEncoding ()
-    {
-	return assignedEncoding;
-    }
-
-    private XmlReader (InputStream stream) throws IOException
-    {
-	super (stream);
-
-	PushbackInputStream	pb;
-        byte			buf [];
-	int			len;
-
-	/*if (stream instanceof PushbackInputStream)
-	    pb = (PushbackInputStream) stream;
-	else*/
-	/**
-	 * Commented out the above code to make sure it works when the
-	 * document is accessed using http. URL connection in the code uses
-	 * a PushbackInputStream with size 7 and when we try to push back
-	 * MAX which default value is set to 512 we get and exception. So
-	 * that's why we need to wrap the stream irrespective of what type
-	 * of stream we start off with.
-	 */
-	pb = new PushbackInputStream (stream, MAXPUSHBACK);
-
-        //
-        // See if we can figure out the character encoding used
-        // in this file by peeking at the first few bytes.
-        //
-	buf = new byte [4];
-	len = pb.read (buf);
-	if (len > 0)
-	    pb.unread (buf, 0, len);
-
-	if (len == 4) switch (buf [0] & 0x0ff) {
-            case 0:
-              // 00 3c 00 3f == illegal UTF-16 big-endian
-              if (buf [1] == 0x3c && buf [2] == 0x00 && buf [3] == 0x3f) {
-		  setEncoding (pb, "UnicodeBig");
-                  return;
-              }
-	      // else it's probably UCS-4
-	      break;
-
-            case '<':      // 0x3c: the most common cases!
-              switch (buf [1] & 0x0ff) {
-                // First character is '<'; could be XML without
-		// an XML directive such as "<hello>", "<!-- ...",
-		// and so on.
-                default:
-                  break;
-
-                // 3c 00 3f 00 == illegal UTF-16 little endian
-                case 0x00:
-                  if (buf [2] == 0x3f && buf [3] == 0x00) {
-		      setEncoding (pb, "UnicodeLittle");
-		      return;
-                  }
-		  // else probably UCS-4
-		  break;
-
-                // 3c 3f 78 6d == ASCII and supersets '<?xm'
-                case '?': 
-                  if (buf [2] != 'x' || buf [3] != 'm')
-		      break;
-		  //
-		  // One of several encodings could be used:
-                  // Shift-JIS, ASCII, UTF-8, ISO-8859-*, etc
-		  //
-		  useEncodingDecl (pb, "UTF8");
-                  return;
-              }
-	      break;
-
-            // 4c 6f a7 94 ... some EBCDIC code page
-            case 0x4c:
-              if (buf [1] == 0x6f
-		    && (0x0ff & buf [2]) == 0x0a7
-		    && (0x0ff & buf [3]) == 0x094) {
-		  useEncodingDecl (pb, "CP037");
-		  return;
-	      }
-	      // whoops, treat as UTF-8
-	      break;
-
-            // UTF-16 big-endian
-            case 0xfe:
-              if ((buf [1] & 0x0ff) != 0xff)
-                  break;
-	      setEncoding (pb, "UTF-16");
-              return;
-
-            // UTF-16 little-endian
-            case 0xff:
-              if ((buf [1] & 0x0ff) != 0xfe)
-                  break;
-	      setEncoding (pb, "UTF-16");
-	      return;
-
-            // default ... no XML declaration
-            default:
-              break;
-        }
-
-	//
-        // If all else fails, assume XML without a declaration, and
-        // using UTF-8 encoding.
-	//
-	setEncoding (pb, "UTF-8");
-    }
-
-    /*
-     * Read the encoding decl on the stream, knowing that it should
-     * be readable using the specified encoding (basically, ASCII or
-     * EBCDIC).  The body of the document may use a wider range of
-     * characters than the XML/Text decl itself, so we switch to use
-     * the specified encoding as soon as we can.  (ASCII is a subset
-     * of UTF-8, ISO-8859-*, ISO-2022-JP, EUC-JP, and more; EBCDIC
-     * has a variety of "code pages" that have these characters as
-     * a common subset.)
-     */
-    private void useEncodingDecl (PushbackInputStream pb, String encoding)
-    throws IOException
-    {
-	byte			buffer [] = new byte [MAXPUSHBACK];
-	int			len;
-	Reader			r;
-	int			c;
-
-	//
-	// Buffer up a bunch of input, and set up to read it in
-	// the specified encoding ... we can skip the first four
-	// bytes since we know that "<?xm" was read to determine
-	// what encoding to use!
-	//
-	len = pb.read (buffer, 0, buffer.length);
-	pb.unread (buffer, 0, len);
-	r = new InputStreamReader (
-		new ByteArrayInputStream (buffer, 4, len),
-		encoding);
-
-	//
-	// Next must be "l" (and whitespace) else we conclude
-	// error and choose UTF-8.
-	//
-	if ((c = r.read ()) != 'l') {
-	    setEncoding (pb, "UTF-8");
-	    return;
-	}
-
-	//
-	// Then, we'll skip any
-	// 	S version="..." 	[or single quotes]
-	// bit and get any subsequent 
-	// 	S encoding="..." 	[or single quotes]
-	//
-	// We put an arbitrary size limit on how far we read; lots
-	// of space will break this algorithm.
-	//
-	StringBuffer	buf = new StringBuffer ();
-	StringBuffer	keyBuf = null;
-	String		key = null;
-	boolean		sawEq = false;
-	char		quoteChar = 0;
-	boolean		sawQuestion = false;
-
-    XmlDecl:
-	for (int i = 0; i < MAXPUSHBACK - 5; ++i) {
-	    if ((c = r.read ()) == -1)
-		break;
-
-	    // ignore whitespace before/between "key = 'value'"
-	    if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
-		continue;
-
-	    // ... but require at least a little!
-	    if (i == 0)
-		break;
-	    
-	    // terminate the loop ASAP
-	    if (c == '?')
-		sawQuestion = true;
-	    else if (sawQuestion) {
-		if (c == '>')
-		    break;
-		sawQuestion = false;
-	    }
-	    
-	    // did we get the "key =" bit yet?
-	    if (key == null || !sawEq) {
-		if (keyBuf == null) {
-		    if (Character.isWhitespace ((char) c))
-			continue;
-		    keyBuf = buf;
-		    buf.setLength (0);
-		    buf.append ((char)c);
-		    sawEq = false;
-		} else if (Character.isWhitespace ((char) c)) {
-		    key = keyBuf.toString ();
-		} else if (c == '=') {
-		    if (key == null)
-			key = keyBuf.toString ();
-		    sawEq = true;
-		    keyBuf = null;
-		    quoteChar = 0;
-		} else
-		    keyBuf.append ((char)c);
-		continue;
-	    }
-
-	    // space before quoted value
-	    if (Character.isWhitespace ((char) c))
-		continue;
-	    if (c == '"' || c == '\'') {
-		if (quoteChar == 0) {
-		    quoteChar = (char) c;
-		    buf.setLength (0);
-		    continue;
-		} else if (c == quoteChar) {
-		    if ("encoding".equals (key)) {
-			assignedEncoding = buf.toString ();
-
-			// [81] Encname ::= [A-Za-z] ([A-Za-z0-9._]|'-')*
-			for (i = 0; i < assignedEncoding.length(); i++) {
-			    c = assignedEncoding.charAt (i);
-			    if ((c >= 'A' && c <= 'Z')
-				    || (c >= 'a' && c <= 'z'))
-				continue;
-			    if (i == 0)
-				break XmlDecl;
-			    if (i > 0 && (c == '-'
-				    || (c >= '0' && c <= '9')
-				    || c == '.' || c == '_'))
-				continue;
-			    // map illegal names to UTF-8 default
-			    break XmlDecl;
-			}
-
-			setEncoding (pb, assignedEncoding);
-			return;
-
-		    } else {
-			key = null;
-			continue;
-		    }
-		}
-	    }
-	    buf.append ((char) c);
-	}
-
-	setEncoding (pb, "UTF-8");
-    }
-
-    private void setEncoding (InputStream stream, String encoding)
-    throws IOException
-    {
-	assignedEncoding = encoding;
-	in = createReader (stream, encoding);
-    }
-
-    /**
-     * Reads the number of characters read into the buffer, or -1 on EOF.
-     */
-    public int read (char buf [], int off, int len) throws IOException
-    {
-	int	val;
-
-	if (closed)
-	    return -1;		// throw new IOException ("closed");
-	val = in.read (buf, off, len);
-	if (val == -1)
-	    close ();
-	return val;
-    }
-
-    /**
-     * Reads a single character.
-     */
-    public int read () throws IOException
-    {
-	int	val;
-
-	if (closed)
-	    throw new IOException ("closed");
-	val = in.read ();
-	if (val == -1)
-	    close ();
-	return val;
-    }
-
-    /**
-     * Returns true iff the reader supports mark/reset.
-     */
-    public boolean markSupported ()
-    {
-	return in == null ? false : in.markSupported ();
-    }
-
-    /**
-     * Sets a mark allowing a limited number of characters to
-     * be "peeked", by reading and then resetting.
-     * @param value how many characters may be "peeked".
-     */
-    public void mark (int value) throws IOException
-    {
-	if (in != null) in.mark (value);
-    }
-
-    /**
-     * Resets the current position to the last marked position.
-     */
-    public void reset () throws IOException
-    {
-	if (in != null) in.reset ();
-    }
-
-    /**
-     * Skips a specified number of characters.
-     */
-    public long skip (long value) throws IOException
-    {
-	return in == null ? 0 : in.skip (value);
-    }
-
-    /**
-     * Returns true iff input characters are known to be ready.
-     */
-    public boolean ready () throws IOException
-    {
-	return in == null ? false : in.ready ();
-    }
-
-    /**
-     * Closes the reader.
-     */
-    public void close () throws IOException
-    {
-	if (closed)
-	    return;
-	in.close ();
-	in = null;
-	closed = true;
-    }
-
-    //
-    // Delegating to a converter module will always be slower than
-    // direct conversion.  Use a similar approach for any other
-    // readers that need to be particularly fast; only block I/O
-    // speed matters to this package.  For UTF-16, separate readers
-    // for big and little endian streams make a difference, too;
-    // fewer conditionals in the critical path!
-    //
-    static abstract class BaseReader extends Reader
-    {
-	protected InputStream	instream;
-	protected byte		buffer [];
-	protected int		start, finish;
-
-	BaseReader (InputStream stream)
-	{
-	    super (stream);
-
-	    instream = stream;
-	    buffer = new byte [8192];
-	}
-
-	public boolean ready () throws IOException
-	{
-	    return instream == null
-		|| (finish - start) > 0
-		||  instream.available () != 0;
-	}
-
-	// caller shouldn't read again
-	public void close () throws IOException
-	{
-	    if (instream != null) {
-		instream.close ();
-		start = finish = 0;
-		buffer = null;
-		instream = null;
-	    }
-	}
-    }
-
-    //
-    // We want this reader, to make the default encoding be as fast
-    // as we can make it.  JDK's "UTF8" (not "UTF-8" till JDK 1.2)
-    // InputStreamReader works, but 20+% slower speed isn't OK for
-    // the default/primary encoding.
-    //
-    static final class Utf8Reader extends BaseReader
-    {
-	// 2nd half of UTF-8 surrogate pair
-	private char		nextChar;
-
-	Utf8Reader (InputStream stream)
-	{
-	    super (stream);
-	}
-
-	public int read (char buf [], int offset, int len) throws IOException
-	{
-	    int i = 0, c = 0;
-
-	    if (len <= 0)
-		return 0;
-	 
-	    // avoid many runtime bounds checks ... a good optimizer
-            // (static or JIT) will now remove checks from the loop.
-            if ((offset + len) > buf.length || offset < 0)
-                throw new ArrayIndexOutOfBoundsException ();
-
-	    // Consume remaining half of any surrogate pair immediately
-	    if (nextChar != 0) {
-		buf [offset + i++] = nextChar;
-		nextChar = 0;
-	    }
-
-	    while (i < len) {
-		// stop or read data if needed
-		if (finish <= start) {
-		    if (instream == null) {
-			c = -1;
-			break;
-		    }
-		    start = 0;
-		    finish = instream.read (buffer, 0, buffer.length);
-		    if (finish <= 0) {
-			this.close ();
-			c = -1;
-			break;
-		    }
-		}
-		
-		//
-		// RFC 2279 describes UTF-8; there are six encodings.
-		// Each encoding takes a fixed number of characters
-		// (1-6 bytes) and is flagged by a bit pattern in the
-		// first byte.  The five and six byte-per-character
-		// encodings address characters which are disallowed
-		// in XML documents, as do some four byte ones.
-		// 
-
-		//
-		// Single byte == ASCII.  Common; optimize.
-		//
-		c = buffer [start] & 0x0ff;
-		if ((c & 0x80) == 0x00) {
-		    // 0x0000 <= c <= 0x007f
-		    start++;
-		    buf [offset + i++] = (char) c;
-		    continue;
-		}
-		
-		//
-		// Multibyte chars -- check offsets optimistically,
-		// ditto the "10xx xxxx" format for subsequent bytes
-		//
-		int		off = start;
-		
-		try {
-		    // 2 bytes
-		    if ((buffer [off] & 0x0E0) == 0x0C0) {
-			c  = (buffer [off++] & 0x1f) << 6;
-			c +=  buffer [off++] & 0x3f;
-
-			// 0x0080 <= c <= 0x07ff
-
-		    // 3 bytes
-		    } else if ((buffer [off] & 0x0F0) == 0x0E0) {
-			c  = (buffer [off++] & 0x0f) << 12;
-			c += (buffer [off++] & 0x3f) << 6;
-			c +=  buffer [off++] & 0x3f;
-
-			// 0x0800 <= c <= 0xffff
-
-		    // 4 bytes
-		    } else if ((buffer [off] & 0x0f8) == 0x0F0) {
-			c  = (buffer [off++] & 0x07) << 18;
-			c += (buffer [off++] & 0x3f) << 12;
-			c += (buffer [off++] & 0x3f) << 6;
-			c +=  buffer [off++] & 0x3f;
-
-			// 0x0001 0000  <= c  <= 0x001f ffff
-
-			// Unicode supports c <= 0x0010 ffff ...
-			if (c > 0x0010ffff)
-			    throw new CharConversionException (
-				"UTF-8 encoding of character 0x00"
-				+ Integer.toHexString (c)
-				+ " can't be converted to Unicode."
-				);
-
-			else if (c > 0xffff) {
-			    // Convert UCS-4 char to surrogate pair (UTF-16)
-			    c -= 0x10000;
-			    nextChar = (char) (0xDC00 + (c & 0x03ff));
-			    c = 0xD800 + (c >> 10);
-			}
-		        // 5 and 6 byte versions are XML WF errors, but
-		        // typically come from mislabeled encodings
-		    } else
-			throw new CharConversionException (
-			    "Unconvertible UTF-8 character"
-			    + " beginning with 0x"
-			    + Integer.toHexString (
-				buffer [start] & 0xff)
-			);
-
-		} catch (ArrayIndexOutOfBoundsException e) {
-		    // off > length && length >= buffer.length
-		    c = 0;
-		}
-
-		//
-		// if the buffer held only a partial character,
-		// compact it and try to read the rest of the
-		// character.  worst case involves three
-		// single-byte reads -- quite rare.
-		//
-		if (off > finish) {
-		    System.arraycopy (buffer, start,
-			    buffer, 0, finish - start);
-		    finish -= start;
-		    start = 0;
-		    off = instream.read (buffer, finish,
-			    buffer.length - finish);
-		    if (off < 0) {
-			this.close ();
-			throw new CharConversionException (
-			    "Partial UTF-8 char");
-		    }
-		    finish += off;
-		    continue;
-		}
-
-		//
-		// check the format of the non-initial bytes
-		//
-		for (start++; start < off; start++) {
-		    if ((buffer [start] & 0xC0) != 0x80) {
-			this.close ();
-			throw new CharConversionException (
-			    "Malformed UTF-8 char -- "
-			    + "is an XML encoding declaration missing?"
-			    );
-		    }
-		}
-
-		//
-		// If this needed a surrogate pair, consume ASAP
-		//
-		buf [offset + i++] = (char) c;
-		if (nextChar != 0 && i < len) {
-		    buf [offset + i++] = nextChar;
-		    nextChar = 0;
-		}
-	    }
-	    if (i > 0)
-		return i;
-	    return (c == -1) ? -1 : 0;
-	}
-    }
-
-    //
-    // We want ASCII and ISO-8859 Readers since they're the most common
-    // encodings in the US and Europe, and we don't want performance
-    // regressions for them.  They're also easy to implement efficiently,
-    // since they're bitmask subsets of UNICODE.
-    //
-    // XXX haven't benchmarked these readers vs what we get out of JDK.
-    //
-    static final class AsciiReader extends BaseReader
-    {
-	AsciiReader (InputStream in) { super (in); }
-
-	public int read (char buf [], int offset, int len) throws IOException
-	{
-	    int		i, c;
-
-	    if (instream == null)
-		return -1;
-
-	    // avoid many runtime bounds checks ... a good optimizer
-            // (static or JIT) will now remove checks from the loop.
-            if ((offset + len) > buf.length || offset < 0)
-                throw new ArrayIndexOutOfBoundsException ();
-
-	    for (i = 0; i < len; i++) {
-		if (start >= finish) {
-		    start = 0;
-		    finish = instream.read (buffer, 0, buffer.length);
-		    if (finish <= 0) {
-			if (finish <= 0)
-			    this.close ();
-			break;
-		    }
-		}
-		c = buffer [start++];
-		if ((c & 0x80) != 0)
-		    throw new CharConversionException (
-			"Illegal ASCII character, 0x"
-			+ Integer.toHexString (c & 0xff)
-		    );
-		buf [offset + i] = (char) c;
-	    }
-	    if (i == 0 && finish <= 0)
-		return -1;
-	    return i;
-	}
-    }
-
-    static final class Iso8859_1Reader extends BaseReader
-    {
-	Iso8859_1Reader (InputStream in) { super (in); }
-
-	public int read (char buf [], int offset, int len) throws IOException
-	{
-	    int		i;
-
-	    if (instream == null)
-		return -1;
-
-	    // avoid many runtime bounds checks ... a good optimizer
-            // (static or JIT) will now remove checks from the loop.
-            if ((offset + len) > buf.length || offset < 0)
-                throw new ArrayIndexOutOfBoundsException ();
-
-	    for (i = 0; i < len; i++) {
-		if (start >= finish) {
-		    start = 0;
-		    finish = instream.read (buffer, 0, buffer.length);
-		    if (finish <= 0) {
-			if (finish <= 0)
-			    this.close ();
-			break;
-		    }
-		}
-		buf [offset + i] = (char) (0x0ff & buffer [start++]);
-	    }
-	    if (i == 0 && finish <= 0)
-		return -1;
-	    return i;
-	}
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/XmlWritable.java b/src/whiteboard/org/apache/xerces/tree/XmlWritable.java
deleted file mode 100644
index a0e901d..0000000
--- a/src/whiteboard/org/apache/xerces/tree/XmlWritable.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import java.io.IOException;
-
-
-/**
- * Objects that can write themselves as XML text do so using this
- * interface.
- *
- * @author David Brownell
- * @version $Revision$
- */
-public interface XmlWritable
-{
-    /**
-     * This is the primary method used to write an object and
-     * its children as XML text.  Implementations with children
-     * should use writeChildrenXml to write those children, to
-     * allow selective overriding.
-     */
-    public void writeXml (XmlWriteContext context)
-    throws IOException;
-
-    /**
-     * Used to write any children of a node.
-     */
-    public void writeChildrenXml (XmlWriteContext context)
-    throws IOException;
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/XmlWriteContext.java b/src/whiteboard/org/apache/xerces/tree/XmlWriteContext.java
deleted file mode 100644
index ddf7fbd..0000000
--- a/src/whiteboard/org/apache/xerces/tree/XmlWriteContext.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * $Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Crimson" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
- * http://www.sun.com.  For more information on the Apache Software 
- * Foundation, please see <http://www.apache.org/>.
- */
-
-package org.apache.xerces.tree;
-
-import java.io.IOException;
-import java.io.Writer;
-
-
-/**
- * This captures context used when writing XML text, such as state
- * used to "pretty print" output or to identify entities which are
- * defined.  Pretty printing is useful when displaying structure in
- * XML documents that need to be read or edited by people (rather
- * than only by machines).
- *
- * @see XmlWritable
- * @see XmlDocument#createWriteContext
- *
- * @author David Brownell
- * @version $Revision$
- */
-public class XmlWriteContext
-{
-    private Writer	writer;
-    private int		indentLevel;
-    private boolean	prettyOutput;
-
-
-    /**
-     * Constructs a write context that doesn't pretty-print output.
-     */
-    public XmlWriteContext (Writer out)
-    {
-	writer = out;
-    }
-
-    /**
-     * Constructs a write context that supports pretty-printing
-     * output starting at the specified number of spaces.
-     */
-    public XmlWriteContext (Writer out, int level)
-    {
-	writer = out;
-	prettyOutput = true;
-	indentLevel = level;
-    }
-
-    /**
-     * Returns the writer to which output should be written.
-     */
-    public Writer getWriter ()
-    {
-	return writer;
-    }
-
-    /**
-     * Returns true if the specified entity was already declared
-     * in this output context, so that entity references may be
-     * written rather than their expanded values.  The predefined
-     * XML entities are always declared.
-     */
-    public boolean isEntityDeclared (String name)
-    {
-	// for contexts tied to documents with DTDs, 
-	// ask that DTD if it knows that entity...
-
-	return ("amp".equals (name)
-		|| "lt".equals (name) || "gt".equals (name)
-		|| "quot".equals (name) || "apos".equals (name));
-    }
-
-    /**
-     * Returns the current indent level, in terms of spaces, for
-     * use in pretty printing XML text.
-     */
-    public int getIndentLevel ()
-    {
-	return indentLevel;
-    }
-
-    /**
-     * Assigns the current indent level, in terms of spaces, for
-     * use in pretty printing XML text.
-     */
-    public void setIndentLevel (int level)
-    {
-	indentLevel = level;
-    }
-
-    /**
-     * If pretty printing is enabled, this writes a newline followed by
-     * <em>indentLevel</em> spaces.  At the beginning of a line, groups
-     * of eight consecutive spaces are replaced by tab characters, for
-     * storage efficiency.
-     *
-     * <P> Note that this method should not be used except in cases
-     * where the additional whitespace is guaranteed to be semantically
-     * meaningless.  This is the default, and is controlled through the
-     * <em>xml:space</em> attribute, inherited from parent elements.
-     * When this attribute value is <em>preserve</em>, this method should
-     * not be used.  Otherwise, text normalization is expected to remove
-     * excess whitespace such as that added by this call.
-     */
-    public void printIndent () throws IOException
-    {
-	int	temp = indentLevel;
-
-	if (!prettyOutput)
-	    return;
-
-	writer.write(XmlDocument.eol);
-	while (temp-- > 0) {
-	    writer.write (' ');
-        }
-    }
-
-    /**
-     * Returns true if writes using the context should "pretty print",
-     * displaying structure through indentation as appropriate.
-     */
-    public boolean isPrettyOutput ()
-    {
-	return prettyOutput;
-    }
-}
diff --git a/src/whiteboard/org/apache/xerces/tree/resources/Messages_en.properties b/src/whiteboard/org/apache/xerces/tree/resources/Messages_en.properties
deleted file mode 100644
index 1d2120b..0000000
--- a/src/whiteboard/org/apache/xerces/tree/resources/Messages_en.properties
+++ /dev/null
@@ -1,85 +0,0 @@
-#
-# $Id$
-#
-
-#
-# Diagnostic messages associated with DOM exceptions.
-#
-D-000 = An index is out of bounds.
-D-001 = The string size is beyond implementation limit.
-D-002 = This node isn't allowed there.
-D-003 = That node doesn't belong in this document.
-D-004 = An invalid character was specified, such as in a name.
-D-005 = Data is not allowed in this node.
-D-006 = The object is read-only.
-D-007 = That node does not exist in this context.
-D-008 = This DOM implementation does not support that node type.
-D-009 = The attribute is bound to a different element.
-D-010 = ?? Unrecognized DOM message code ??
-
-#
-# Diagnostic messages associated with AttributeNode.
-#
-A-000 = Attribute is already bound to an element: {0}.
-A-001 = Attribute's element is not known.
-A-002 = Can't happen.
-
-#
-# Diagnostic messages associated with AttributeSet.
-# 
-A-003 = Not an attribute.
-A-004 =	Attribute is already bound to an element.
-
-#
-# Diagnostic messages associated with Doctype.
-# 
-DT-000 = NYI -- dtd clone.
-
-#
-# Diagnostic messages associated with ElementNode.
-# 
-EN-000 = Namespace prefix undeclared: {0}.
-EN-001 = Can't clone.
-EN-002 = Element has no tag.
-#
-# Diagnostic messages associated with SimpleElementFactory.
-# 
-SEF-000 = Bad mapping of '{0}' to class '{1}', doesn't subclass org.apache.crimson.tree.ElementNode.
-SEF-001 = Bad mapping of key '{0}' to class ' {1}', not found: {2}.
-SEF-002 = Bad mapping of key '{0}' to class -- not a string or Class.
-SEF-003 = Can't instantiate element for tag '{0}' from class '{1}', {2}. 
-
-#
-# Diagnostic messages associated with TreeWalker.
-# 
-TW-000  = unknown node type:{0}
-TW-001 = current == null.
-TW-002 = parent == null.
-TW-003 = Node is not a org.apache.crimson.tree implementation.
-TW-004 = Initial node cannot be null.
-
-#
-# Diagnostic messages associated with XmlDocument.
-# 
-XD-000 = null id.
-XD-001 = NYI -- deep.
-XD-002 = null entity name.
-XD-003 = Entity undeclared, can't write reference: {0}. 
-
-#
-# Diagnostic messages associated with XmlDocumentBuilder.
-# 
-XDB-000 = element stack not empty.
-XDB-001 = Attribute value may not have a colon: {0}. 
-XDB-002 = Parser returned illegal attributes:{0}.
-XDB-003 = Element names may have at most one colon: {0}. 
-XDB-004 = DOM Error: {0}.
-XDB-005 = Element prefix is undeclared: {0}.
-XDB-006 = Attribute prefix is undeclared: {0}.
-XDB-007 = Attribute names may have at most one colon: {0}.
-XDB-008 = Scoped attribute appears twice: {0}. 
-XDB-009 = can't end element <{0}> because current element is {1}.
-XDB-010 = Processing Instruction target names must be unqualified.
-XDB-011 = can't end entity <{0}> because current entity is {1}.
-XDB-012 = Entity names must be unqualified.
-XDB-013 = Notation names must be unqualified.
diff --git a/tests/Makefile b/tests/Makefile
deleted file mode 100644
index 98fafca..0000000
--- a/tests/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-
-TARGETS=
-
-DIRS = dom
-
-TOP = ../
-include $(TOP)/src/Makefile.incl
-CLPATH = $(TOP)/tests;$(CLPATH)
diff --git a/tests/dom/DTest.java b/tests/dom/DTest.java
deleted file mode 100644
index e5ff55a..0000000
--- a/tests/dom/DTest.java
+++ /dev/null
@@ -1,1758 +0,0 @@
-/* $Id$ */
-/*
- * The Apache Software License, Version 1.1
- * 
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- * 
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- * 
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache\@apache.org.
- * 
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- * 
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- * 
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation, and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.ibm.com .  For more information
- * on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package dom;
-
-import org.w3c.dom.*;
-import java.lang.reflect.*;
-import java.io.StringWriter;
-import java.io.PrintWriter;
-import dom.util.Assertion;
-
-/**
- * This class tests methods for XML DOM implementation
- * version 2.0 10/12/98
- * 
- * DOMException errors are tested by calls to DOMExceptionsTest from: Main, docBuilder...
- *
- * @author Philip W. Davis
- */
- 
-public class DTest {
-	
-	public static Element 		testElementNode;
-	public static Attr 		testAttributeNode;
-	public static Text 		testTextNode;
-	public static CDATASection 	testCDATASectionNode;
-	public static EntityReference 	testEntityReferenceNode;
-	public static Entity 		testEntityNode;
-	public static ProcessingInstruction testProcessingInstructionNode;
-	public static Comment 		testCommentNode;
-	public static Document 		testDocumentNode;
-	public static DocumentType 	testDocumentTypeNode;
-	public static DocumentFragment 	testDocumentFragmentNode;
-	public static Notation 		testNotationNode;
-
-/**
- * 
- * version 2.0 10/12/98
- *
- * @author Philip W. Davis
- */
-public DTest() {
-	super();
-	
-}
-/**
- * version 3.0 01/25/99
- *  
- * @return org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public Document createDocument() {
-	return new org.apache.xerces.dom.DocumentImpl();	//Replace with a Document creator
-}
-/**
- * version 3.0 01/25/99
- * 
- * @return org.w3c.dom.DocumentType
- * @param name java.lang.String
- *
- * @author Philip W. Davis
- */
-public DocumentType createDocumentType(Document doc, String name) {
-	return ((org.apache.xerces.dom.DocumentImpl) doc).createDocumentType(name, null, null);	//Replace with a DocumentType creator
-}
-/**
- * version 3.0 01/25/99
- *  
- * @return org.w3c.dom.Entity
- * @param doc org.w3c.dom.Document
- * @param name java.lang.String
- *
- * @author Philip W. Davis
- */
-public Entity createEntity(Document doc, String name) {
-	return new org.apache.xerces.dom.EntityImpl((org.apache.xerces.dom.DocumentImpl)doc, name);	//Replace with an Entity creator
-}
-/**
- * version 3.0 01/25/99
- * 
- * @return org.w3c.dom.Notation
- * @param doc org.w3c.dom.Document
- * @param name java.lang.String
- *
- * @author Philip W. Davis
- */
-public Notation createNotation(Document doc, String name) {
-	return new org.apache.xerces.dom.NotationImpl((org.apache.xerces.dom.DocumentImpl) doc, name);	// Replace with a Notation creator
-}
-/**
- * This method builds test documents for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- * @param name document's name
- * @param type document's type
- *
- * @author Philip W. Davis
- */
-public void docBuilder(org.w3c.dom.Document document, String name)
-{
-	Document doc = document;
-	boolean OK = true;
-		
-	Element docFirstElement = doc.createElement(name + "FirstElement");
-	doc.appendChild(docFirstElement);
-	docFirstElement.setAttribute(name + "FirstElement", name + "firstElement");
-	
-	ProcessingInstruction docProcessingInstruction = doc.createProcessingInstruction(name +
-					"TargetProcessorChannel", "This is " + doc + "'s processing instruction");
-	docFirstElement.appendChild(docProcessingInstruction);
-	
-	Element docBody = doc.createElement(name + "TestBody");
-	docFirstElement.appendChild(docBody);
-	
-	Element docBodyLevel21 = doc.createElement(name + "BodyLevel21");
-	Element docBodyLevel22 = doc.createElement(name + "BodyLevel22");
-	Element docBodyLevel23 = doc.createElement(name + "BodyLevel23");
-	Element docBodyLevel24 = doc.createElement(name + "BodyLevel24");
-	docBody.appendChild(docBodyLevel21);
-	docBody.appendChild(docBodyLevel22);
-	docBody.appendChild(docBodyLevel23);
-	docBody.appendChild(docBodyLevel24);
-	
-	Element docBodyLevel31 = doc.createElement(name + "BodyLevel31");
-	Element docBodyLevel32 = doc.createElement(name + "BodyLevel32");
-	Element docBodyLevel33 = doc.createElement(name + "BodyLevel33");
-	Element docBodyLevel34 = doc.createElement(name + "BodyLevel34");
-	docBodyLevel21.appendChild(docBodyLevel31);
-	docBodyLevel21.appendChild(docBodyLevel32);
-	docBodyLevel22.appendChild(docBodyLevel33);
-	docBodyLevel22.appendChild(docBodyLevel34);
-	
-	Text docTextNode11 = doc.createTextNode(name + "BodyLevel31'sChildTextNode11");
-	Text docTextNode12 = doc.createTextNode(name + "BodyLevel31'sChildTextNode12");
-	Text docTextNode13 = doc.createTextNode(name + "BodyLevel31'sChildTextNode13");
-	Text docTextNode2 = doc.createTextNode(name + "TextNode2");
-	Text docTextNode3 = doc.createTextNode(name + "TextNode3");
-	Text docTextNode4 = doc.createTextNode(name + "TextNode4");
-	docBodyLevel31.appendChild(docTextNode11);
-	docBodyLevel31.appendChild(docTextNode12);
-	docBodyLevel31.appendChild(docTextNode13);
-	docBodyLevel32.appendChild(docTextNode2);
-	docBodyLevel33.appendChild(docTextNode3);
-	docBodyLevel34.appendChild(docTextNode4);
-	
-	CDATASection docCDATASection = doc.createCDATASection("<![CDATA[<greeting>Hello, world!</greeting>]]>");
-	docBodyLevel23.appendChild(docCDATASection);
-	
-	Comment docComment = doc.createComment("This should be a comment of some kind ");
-	docBodyLevel23.appendChild(docComment);
-	
-	EntityReference docReferenceEntity = doc.createEntityReference("ourEntityNode");
-	docBodyLevel24.appendChild(docReferenceEntity);
-
-	DTest make = new DTest();
-	Notation docNotation = make.createNotation(doc, "ourNotationNode");
-//	NotationImpl docNotation = new NotationImpl((DocumentImpl) doc, "ourNotationNode");//*****?
-	DocumentType docType = (DocumentType)doc.getFirstChild();
-	docType.getNotations().setNamedItem(docNotation);
-	
-	DocumentFragment docDocFragment = doc.createDocumentFragment();
-	
-//	System.out.println("This document's first element name is " + docFirstElement.getTagName() + "\n");
-
-
-//***********Following are for errorTests
-	Text docNode3 = doc.createTextNode(name + "docTextNode3");
-	Text docNode4 = doc.createTextNode(name + "docTextNode4");
-	
-	Entity docEntity = (Entity) doc.getDoctype().getEntities().getNamedItem("ourEntityNode"); // Get the Entity node
-	DocumentType docDocType = (DocumentType) doc.getFirstChild();	// Get the DocumentType node
-	EntityReference entityReferenceText = (EntityReference) doc.getLastChild().getLastChild().getLastChild().getFirstChild();
-	Text entityReferenceText2 = doc.createTextNode("entityReferenceText information");
-//************************************************* ERROR TESTS
-	DTest tests = new DTest();
-
-	OK &= Assertion.assert(tests.DOMExceptionsTest(document, "appendChild", new Class[]{Node.class}, new Object[]{docBody}, DOMException.HIERARCHY_REQUEST_ERR )); 
-	OK &= Assertion.assert(tests.DOMExceptionsTest(docNode3, "appendChild", new Class[]{Node.class}, new Object[]{docNode4}, DOMException.HIERARCHY_REQUEST_ERR )); 
-	OK &= Assertion.assert(tests.DOMExceptionsTest(doc, "insertBefore", new Class[]{Node.class, Node.class}, new Object[]{docEntity, docFirstElement}, DOMException.HIERARCHY_REQUEST_ERR )); 
-	OK &= Assertion.assert(tests.DOMExceptionsTest(doc, "replaceChild", new Class[]{Node.class, Node.class}, new Object[]{docCDATASection, docFirstElement}, DOMException.HIERARCHY_REQUEST_ERR )); 
-
-        docFirstElement.setNodeValue("This shouldn't do anything!");
-	OK &= Assertion.assert(docFirstElement.getNodeValue() == null);
-        docReferenceEntity.setNodeValue("This shouldn't do anything!");
-	OK &= Assertion.assert(docReferenceEntity.getNodeValue() == null);
-        docEntity.setNodeValue("This shouldn't do anything!");
-	OK &= Assertion.assert(docEntity.getNodeValue() == null);
-        doc.setNodeValue("This shouldn't do anything!");
-	OK &= Assertion.assert(doc.getNodeValue() == null);
-        docType.setNodeValue("This shouldn't do anything!");
-	OK &= Assertion.assert(docType.getNodeValue() == null);
-        docDocFragment.setNodeValue("This shouldn't do anything!");
-	OK &= Assertion.assert(docDocFragment.getNodeValue() == null);
-        docNotation.setNodeValue("This shouldn't do anything!");
-	OK &= Assertion.assert(docNotation.getNodeValue() == null);
-
-	OK &= Assertion.assert(tests.DOMExceptionsTest(docReferenceEntity, "appendChild", new Class[]{Node.class}, new Object[]{entityReferenceText2 }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(docBodyLevel32, "insertBefore", new Class[]{Node.class, Node.class}, new Object[]{docTextNode11,docBody }, DOMException.NOT_FOUND_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(docBodyLevel32, "removeChild", new Class[]{Node.class}, new Object[]{docFirstElement}, DOMException.NOT_FOUND_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(docBodyLevel32, "replaceChild", new Class[]{Node.class, Node.class}, new Object[]{docTextNode11,docFirstElement }, DOMException.NOT_FOUND_ERR ));
-
-
-//!! Throws a NOT_FOUND_ERR	********
-	 
-	 //	docBodyLevel32.getAttributes().removeNamedItem(testAttribute.getName()); 	16  // To test removeNamedItem
-	 
-}//END OF DOCBUILDER
-/**
- * version 3.0 01/25/99
- * 
- * @return boolean
- * @param node java.lang.Object
- * @param mNameIndex int
- * @param signatureIndex int
- * @param parameters java.lang.Object[]
- * @param code short
- *
- * @author Philip W. Davis
- */
-public static boolean DOMExceptionsTest(Object node, String methodName, Class[] methodSignature, Object[] parameters, short code) {
-	
-	
-	boolean asExpected = false;
-	Method method;
-
-	try
-	{
-		method = node.getClass().getMethod(methodName,methodSignature);
-		method.invoke(node, parameters);
-	}catch(InvocationTargetException exc)
-	{
-		Throwable realE = exc.getTargetException(); 
-		if(realE instanceof DOMException)
-		{
-			asExpected = (((DOMException)realE).code== code);
-			if(!asExpected)
-				System.out.println("Wrong DOMException(" + ((DOMException)realE).code + ")");
-		}
-		else
-			System.out.println("Wrong Exception (" + code + ")");
-
-		if(!asExpected)
-		{
-			System.out.println("Expected DOMException (" + code + ") not thrown");			
-		}
-	}catch(Exception exc)
-	{
-		System.out.println("test invocation failure (" + exc + ")");
-	}
-	
-	
-	return (asExpected);
-}
-
-/**
- * @author Philip W. Davis
- * @param document org.w3c.dom.Document
- */
-public void findTestNodes(Document document) {
-
-
-
-
-	Node node = document;
-	int nodeCount = 0;
-
-	// Walk the tree until you find and assign all node types needed that exist.
-	while (node != null && nodeCount < 12)
-	{
-
-		switch (node.getNodeType())
-	{
-		case org.w3c.dom.Node.ELEMENT_NODE :
-			if (testElementNode == null) {testElementNode = (Element)node; nodeCount++;}
-			break;
-		case org.w3c.dom.Node.ATTRIBUTE_NODE :
-			if (testAttributeNode == null) {testAttributeNode = (Attr)node; nodeCount++;}
-			break;
-		case org.w3c.dom.Node.TEXT_NODE :
-			if (testTextNode == null) {testTextNode = (Text)node; nodeCount++;}
-			break;
-		case org.w3c.dom.Node.CDATA_SECTION_NODE :
-			if (testCDATASectionNode == null) {testCDATASectionNode = (CDATASection)node; nodeCount++;}
-			break;
-		case org.w3c.dom.Node.ENTITY_REFERENCE_NODE :
-			if (testEntityReferenceNode == null) {testEntityReferenceNode = (EntityReference)node; nodeCount++;}
-			break;
-		case org.w3c.dom.Node.ENTITY_NODE :
-			if (testEntityNode == null) {testEntityNode = (Entity)node; nodeCount++;}
-			break;
-		case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE :
-			if (testProcessingInstructionNode == null) {testProcessingInstructionNode = (ProcessingInstruction)node; nodeCount++;}
-			break;
-		case org.w3c.dom.Node.COMMENT_NODE :
-			if (testCommentNode == null) {testCommentNode = (Comment)node; nodeCount++;}
-			break;
-		case org.w3c.dom.Node.DOCUMENT_TYPE_NODE :
-			if (testDocumentTypeNode == null) {testDocumentTypeNode = (DocumentType)node; nodeCount++;}
-			break;
-		case org.w3c.dom.Node.DOCUMENT_FRAGMENT_NODE :
-			if (testDocumentFragmentNode == null) {testDocumentFragmentNode = (DocumentFragment)node; nodeCount++;}
-			break;
-		case org.w3c.dom.Node.NOTATION_NODE :
-			if (testNotationNode == null) {testNotationNode = (Notation)node; nodeCount++;}
-			break;
-		case org.w3c.dom.Node.DOCUMENT_NODE :
-			if (testDocumentNode == null) {testDocumentNode = (Document)node; nodeCount++;}
-			break;
-		default:
-	}// End of switch
-
-	
-
-
-	}// End of while
-	
-
-
-
-
-
-
-
-
-
-
-
-
-
-	
-}
-
-/**
- * @author Philip W. Davis
- * @param document org.w3c.dom.Document
- */
-public void findTestNodes(Node node) {
-
-	DTest test = new DTest();
-	Node kid;
-	// Walk the tree until you find and assign all node types needed that exist.
-	
-		
-	if (node.getFirstChild() != null)
-	{
-		kid = node.getFirstChild();
-		test.findTestNodes(kid);
-	}
-			
-				
-	if (node.getNextSibling() != null)
-	{
-		kid = node.getNextSibling();
-		test.findTestNodes(kid);
-	}
-
-		
-	switch (node.getNodeType())
-	{
-		case org.w3c.dom.Node.ELEMENT_NODE :
-			if (testElementNode == null) {testElementNode = (Element)node; }
-			break;
-		case org.w3c.dom.Node.ATTRIBUTE_NODE :
-			if (testAttributeNode == null) {testAttributeNode = (Attr)node; }
-			break;
-		case org.w3c.dom.Node.TEXT_NODE :
-			if (testTextNode == null) {testTextNode = (Text)node; }
-			break;
-		case org.w3c.dom.Node.CDATA_SECTION_NODE :
-			if (testCDATASectionNode == null) {testCDATASectionNode = (CDATASection)node; }
-			break;
-		case org.w3c.dom.Node.ENTITY_REFERENCE_NODE :
-			if (testEntityReferenceNode == null) {testEntityReferenceNode = (EntityReference)node;}
-			break;
-		case org.w3c.dom.Node.ENTITY_NODE :
-			if (testEntityNode == null) {testEntityNode = (Entity)node;}
-			break;
-		case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE :
-			if (testProcessingInstructionNode == null) {testProcessingInstructionNode = (ProcessingInstruction)node;}
-			break;
-		case org.w3c.dom.Node.COMMENT_NODE :
-			if (testCommentNode == null) {testCommentNode = (Comment)node;}
-			break;
-		case org.w3c.dom.Node.DOCUMENT_TYPE_NODE :
-			if (testDocumentTypeNode == null) {testDocumentTypeNode = (DocumentType)node; }
-			break;
-		case org.w3c.dom.Node.DOCUMENT_FRAGMENT_NODE :
-			if (testDocumentFragmentNode == null) {testDocumentFragmentNode = (DocumentFragment)node;}
-			break;
-		case org.w3c.dom.Node.NOTATION_NODE :
-			if (testNotationNode == null) {testNotationNode = (Notation)node;}
-			break;
-		case org.w3c.dom.Node.DOCUMENT_NODE :
-			if (testDocumentNode == null) {testDocumentNode = (Document)node;}
-			break;
-		default:
-	}// End of switch
-	
-
-}
-	
-/**
- * 
- * version 2.0 10/12/98
- *
- * @author Philip W. Davis
- */
-
-public static void main(String args[]) {
-    System.out.println("# main()");
-	
-	DTest test = new DTest();
-
-	long avgTime = 0;
-	boolean OK = true;
-	long startTime = 0;//****************Time the whole thing for efficiency of DOM implementation
-	 
-//	for (int i=0; i< 1000; i++)
-//	{	
-		startTime = System.currentTimeMillis();
-//		if(!OK)
-//		break;
-
-	Document d = test.createDocument();
-//	Document z = test.createDocument();
-
-	DocumentType docDocType = test.createDocumentType(d,"testDocument1");
-	d.appendChild(docDocType);
-
-	Entity docEntity = test.createEntity( d, "ourEntityNode");
-	Text entityChildText = d.createTextNode("entityChildText information"); // Build a branch for entityReference tests
-        ((org.apache.xerces.dom.NodeImpl)docEntity).setReadOnly(false, true);
-	docEntity.appendChild(entityChildText);					  // & for READONLY_ERR tests
-        ((org.apache.xerces.dom.NodeImpl)docEntity).setReadOnly(true, true);
-	docDocType.getEntities().setNamedItem(docEntity);
-	
-	test.docBuilder(d, "d");
-
-	test.findTestNodes((Node)d);
-//	test.docBuilder(z, "z");
-	try {
-/**/		test.testAttr(d);
-		test.testCDATASection(d);
-		test.testCharacterData(d);
-		test.testChildNodeList(d);
-		test.testComment(d);
-		test.testDeepNodeList(d);
-		test.testDocument(d);
-		test.testDocumentFragment(d);
-		test.testDocumentType(d);
-		test.testDOMImplementation(d);
-		test.testElement(d);
-		test.testEntity(d);
-		test.testEntityReference(d);
-		test.testNode(d);
-		test.testNotation(d);
-		test.testPI(d);
-		test.testText(d);
-/**/		test.testDOMerrors(d);
-	
-//!! Throws WRONG_DOCUMENT_ERR **********
-		
-	//	z.appendChild(d.createComment("Test doc d comment"));// Tries to append z document with document d comment
-	//	d.getDocumentElement().appendChild(z.createElement("newZdocElement"));// Tries to append d document with document z Element
-	//	d.getLastChild().getLastChild().insertBefore(z.createElement("newZdocElement"),d.getLastChild().getLastChild().getFirstChild());// Tries to insert into d document with document z Element
-	//	d.replaceChild(z.createElement("newZdocElement"),d.getLastChild().getLastChild().getFirstChild());	// Tries to replace in d document with document z Element
-
-	/*	Attribute newAttribute = d.createAttribute("newAttribute");
-		d.getDocumentElement().setAttributeNode(newAttribute);
-		d.getDocumentElement().getAttributes().setNamedItem(z.createAttribute("newzAttribute"));
-	*/
-		
-//!! Throws INVALID_CHARACTER_ERR **********
-	// ******This just gets us through each method. JKess has a comprehensive test of Invalid Names******
-	//	d.createAttribute("Invalid Name"); // Name with blank space
-	//	d.createElement("5InvalidName"); // Name starts with numeric
-	//	d.createProcessingInstruction("This is the target processor channel","InvalidName>");// Name ends with >
-	//	d.getDocumentElement().setAttribute("Invalid%Name",""); // Name contains %
-		
-
-//!!	******** NO_DATA_ALLOWED_ERR ********No cases to test as of 9/15
-
-
-//!! 	******** NO_MODIFICATION_ALLOWED_ERR ******** When read only exists
-	/*
-		
-
-		
-		//**** FOR Element when read only exists********
-		.removeAttribute("aString");		   //***** Not until read only exists.
-		.removeAttributeNode(Attribute); 	   //***** Not until read only exists.
-		.setAttribute("aString", "anotherString"); //***** Not until read only exists.
-		
-		
-		//**** FOR Node when read only exists********
-		.appendChild(aNode);			//***** Not until read only exists.
-		.insertBefore(aNode, AnotherNode);	//***** Not until read only exists.
-		.removeChild(aNode);			//***** Not until read only exists.
-		.replaceChild(aNode);			//***** Not until read only exists.
-		
-		.splitText(2); //***** Not until read only exists.
-		
-		.setNamedItem(Node); //***** Not until read only exists.
-	*/
-	
-
-//!!******** NOT_SUPPORTED_ERR	********For HTML when implemented
-	/*
-		.createCDATASection("String stuff");
-		.createEntityReference("String stuff");
-		.createProcessingInstruction("String stuff", "Some more String stuff");
-	*/
-
-	} catch (Exception e) {
-		System.out.println("Exception is: ");
-		e.printStackTrace();
-		OK = false;
-		
-	}
-//System.err.println("Elapsed time (measured in seconds): " +   ((System.currentTimeMillis() - startTime) / 1000.0));
-	avgTime += System.currentTimeMillis() - startTime;
-//	}//END OF FOR
-	  
-	
-//	System.err.println("Elapsed time (measured in seconds): " +
-//					   ((System.currentTimeMillis() - startTime) / 1000.0));
-//	      System.err.println("Elapsed time (measured in mili-seconds): " +
-//					   ((System.currentTimeMillis() - startTime)));
-
-
-//	System.err.println("Average Elapsed time (measured in seconds): " + (avgTime/10000000.0) );
-
-}
-/**
- * This method tests Attr methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testAttr(org.w3c.dom.Document document)
-{
-	
-	Node node;	
-	Attr attributeNode, attribute2;
-	String compare;
-	boolean T = true;
-	boolean F = false;
-	boolean OK = true;
-// For debugging*****	println("\n          testAttr's outputs:\n");
-
-	Attr testAttribute = document.createAttribute("testAttribute");
-	testAttribute.setValue("testAttribute's value");
-	node = document.getDocumentElement(); // node gets first element
-	((Element)node).setAttributeNode(testAttribute);
-	attributeNode = ((Element)node).getAttributeNode("testAttribute");
-
-	compare = "testAttribute";
-	if (!compare.equals(attributeNode.getName()))
-	{
-		System.out.println("Warning!!! Attr's 'getName' method failed to work properly!");
-		OK = false;
-	}
-	compare = "testAttribute's value";
-	if (!compare.equals(attributeNode.getNodeValue()))
-	{
-		System.out.println("Warning!!! Attr's 'getNodeValue' method failed to work properly!");
-		OK = false;
-	}
-	if (! T ==attributeNode.getSpecified())
-	{
-		System.out.println("Warning!!! Attr's 'getSpecified' method failed to work properly!");
-		OK = false;
-	}
-	
-	if (!compare.equals(attributeNode.getValue()))
-	{
-		System.out.println("Warning!!! Attr's 'getValue' method failed to work properly!");
-		OK = false;
-	}
-	
-	attributeNode.setNodeValue("Reset Value");
-	compare = "Reset Value";
-	if (!compare.equals(attributeNode.getNodeValue()))
-	{
-		System.out.println("Warning!!! Attr's 'setNodeValue' method failed to work properly!");
-		OK = false;
-	}
-	((org.apache.xerces.dom.AttrImpl)attributeNode).setSpecified(F);//***** How do we change this for external use??
-	if (! F ==attributeNode.getSpecified())
-	{
-		System.out.println("Warning!!! Attr's 'setSpecified' method failed to work properly!");
-		OK = false;
-	}
-	
-	attributeNode.setValue(null);
-	if (! attributeNode.getValue().equals(""))
-	{
-		System.out.println("Warning!!! Attr's 'setValue' to 'null' method failed to work properly!");
-		OK = false;
-	}
-	
-	attributeNode.setValue("Another value ");
-	compare = "Another value ";
-	if (!compare.equals(attributeNode.getValue()))
-	{
-		System.out.println("Warning!!! Attr's 'setValue' method failed to work properly!");
-		OK = false;
-	}
-
-	node = attributeNode.cloneNode(T);//*****?
-	// Check nodes for equality, both their name and value or lack thereof
-	if (! (node.getNodeName().equals(attributeNode.getNodeName()) &&	     // Compares node names for equality
-	      (node.getNodeValue() != null && attributeNode.getNodeValue() != null)  // Checks to make sure each node has a value node
-	    ?  node.getNodeValue().equals(attributeNode.getNodeValue()) 	     // If both have value nodes test those value nodes for equality
-	    : (node.getNodeValue() == null && attributeNode.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
-		{	
-			System.out.println("'cloneNode' did not clone the Attribute node correctly");
-			OK = false;
-		}
-		// Deep clone test comparison is in testNode & testDocument
-
-//************************************************* ERROR TESTS
-	DTest tests = new DTest();
-        Assertion.assert(
-          tests.DOMExceptionsTest(document.getDocumentElement(),
-                                  "appendChild",
-                                  new Class[]{Node.class},
-                                  new Object[]{attributeNode},
-                                  DOMException.HIERARCHY_REQUEST_ERR));
-
-	attribute2 = document.createAttribute("testAttribute2");
-        Assertion.assert(
-          tests.DOMExceptionsTest(document.getDocumentElement(),
-                                  "removeAttributeNode",
-                                  new Class[]{Attr.class},
-                                  new Object[]{attribute2},
-                                  DOMException.NOT_FOUND_ERR));
-
-        Element element = (Element)document.getLastChild().getLastChild();
-        // Tests setNamedItem
-        Assertion.assert(
-          tests.DOMExceptionsTest(element,
-                                  "setAttributeNode",
-                                  new Class[]{Attr.class},
-                                  new Object[]{testAttribute},
-                                  DOMException.INUSE_ATTRIBUTE_ERR));
-	
-	if (! OK)
-		System.out.println("\n*****The Attr method calls listed above failed, all others worked correctly.*****");
-//	println("");
-}
-/**
- * This method tests CDATASection methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testCDATASection(org.w3c.dom.Document document)
-{
-	
-	Node node, node2;
-	boolean T = true;
-	boolean OK = true;
-// For debugging*****	println("\n          testCDATASection's outputs:\n");
-	node = document.getDocumentElement().getElementsByTagName("dBodyLevel23").item(0).getFirstChild(); // node gets CDATASection node
-
-	node2 = node.cloneNode(T);//*****?
-	// Check nodes for equality, both their name and value or lack thereof
-	if (! (node.getNodeName().equals(node2.getNodeName()) && 		// Compares node names for equality
-	      (node.getNodeValue() != null && node2.getNodeValue() != null)     // Checks to make sure each node has a value node
-	    ?  node.getNodeValue().equals(node2.getNodeValue()) 		// If both have value nodes test those value nodes for equality
-	    : (node.getNodeValue() == null && node2.getNodeValue() == null)))	// If one node doesn't have a value node make sure both don't
-	{
-		System.out.println("'cloneNode' did not clone the CDATASection node correctly");
-		OK = false;
-	}
-	// Deep clone test comparison is in testNode & testDocument
-	
-// For debugging*****	println("All CDATASection method calls worked correctly.");
-		
-	if (! OK)
-		System.out.println("\n*****The CDATASection method calls listed above failed, all others worked correctly.*****");
-//	println("");
-}
-/**
- * This method tests CharacterData methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testCharacterData(org.w3c.dom.Document document)
-{
-	CharacterData charData;
-	String compareData, newData, resetData;
-	boolean OK = true;
-// For debugging*****	println("\n          testCharacterData's outputs:\n");
-	charData = (CharacterData) document.getDocumentElement().getElementsByTagName("dBodyLevel31").item(0).getFirstChild(); // charData gets textNode11
-	compareData = "dBodyLevel31'sChildTextNode11";
-	if (!compareData.equals(charData.getData()))
-	{
-		System.out.println("Warning!!! CharacterData's 'getData' failed to work properly!\n This may corrupt other CharacterData tests!!!*****");
-		OK = false;
-	}	
-	
-	resetData = charData.getData();
-	//  println("This node's original data is: " + charData.getData());
-
-	newData = " This is new data for this node";
-	compareData = charData.getData() + newData;
-	charData.appendData(newData);
-	if (!compareData.equals(charData.getData()))
-	{
-		System.out.println("Warning!!! CharacterData's 'appendData' failed to work properly!");
-		OK = false;
-	}
-	//	println("This node's appended data is: " + charData.getData());
-
-	compareData = "dBodyLevel";
-	charData.deleteData(10, 100);
-	if (!compareData.equals(charData.getData()))
-	{
-		System.out.println("Warning!!! CharacterData's 'deleteData' failed to work properly!");
-		OK = false;
-	}
-	//  println("This node's partially deleted data is: " + charData.getData());
-
-	int length = 10;
-	if (!(length == charData.getLength()))
-	{
-		System.out.println("Warning!!! CharacterData's 'getLength' failed to work properly!");
-		OK = false;
-	}
-	//  println("This node's data length is: " + charData.getLength());
-
-	compareData = "dBody' This is data inserted into this node'Level";
-	charData.insertData(5, "' This is data inserted into this node'");
-	if (!compareData.equals(charData.getData()))
-	{
-		System.out.println("Warning!!! CharacterData's 'insertData' failed to work properly!");
-		OK = false;
-	}
-	//	println("This node's updated with insert data is: " + charData.getData());
-
-	compareData = "dBody' This is ' replacement data'ted into this node'Level";
-	charData.replaceData(15, 10, "' replacement data'");
-	if (!compareData.equals(charData.getData()))
-	{
-		System.out.println("Warning!!! CharacterData's 'replaceData' failed to work properly!");
-		OK = false;
-	}
-	//	println("This node's updated with replacement data is: " +charData.getData());
-
-	compareData = "New data A123456789B123456789C123456789D123456789E123456789";
-	charData.setData("New data A123456789B123456789C123456789D123456789E123456789");
-	if (!compareData.equals(charData.getData()))
-	{
-		System.out.println("Warning!!! CharacterData's 'setData' failed to work properly!");
-		OK = false;
-	}
-	//	println("This node's new data via setData: " + charData.getData());
-
-	compareData = "123456789D123456789E123456789";
-	if (!compareData.equals(charData.substringData(30, 30)))
-	{
-		System.out.println("Warning!!! CharacterData's 'substringData' failed to work properly!");
-		OK = false;
-	}
-	//	println("Using subString 30,30 you get:" + charData.substringData(30,30));
-
-	compareData = "New data A123456789B12345";
-	if (!compareData.equals(charData.substringData(0, 25)))
-	{
-		System.out.println("Warning!!! CharacterData's 'substringData' failed to work properly!");
-		OK = false;
-	}
-	//	println("Using subString 0,25 you get:" + charData.substringData(0,25));
-
-//************************************************* ERROR TESTS
-	DTest tests = new DTest();
-
-//!! Throws INDEX_SIZE_ERR ********************
-	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "deleteData", new Class[]{int.class, int.class}, 
-			new Object[]{new Integer(-1),new Integer(5) }, DOMException.INDEX_SIZE_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "deleteData", new Class[]{int.class, int.class}, 
-			new Object[]{new Integer(2),new Integer(-1) }, DOMException.INDEX_SIZE_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "deleteData", new Class[]{int.class, int.class}, 
-			new Object[]{new Integer(100),new Integer(5) }, DOMException.INDEX_SIZE_ERR ));
-	
-	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "insertData", new Class[]{int.class, String.class}, 
-			new Object[]{new Integer(-1),"Stuff inserted" }, DOMException.INDEX_SIZE_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "insertData", new Class[]{int.class, String.class}, 
-			new Object[]{new Integer(100),"Stuff inserted" }, DOMException.INDEX_SIZE_ERR ));
-	
-	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "replaceData", new Class[]{int.class, int.class, String.class}, 
-			new Object[]{new Integer(-1),new Integer(5),"Replacement stuff" }, DOMException.INDEX_SIZE_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "replaceData", new Class[]{int.class, int.class, String.class}, 
-			new Object[]{new Integer(100),new Integer(5),"Replacement stuff" }, DOMException.INDEX_SIZE_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "replaceData", new Class[]{int.class, int.class, String.class}, 
-			new Object[]{new Integer(2),new Integer(-1),"Replacement stuff" }, DOMException.INDEX_SIZE_ERR ));
-	
-	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "substringData", new Class[]{int.class, int.class}, 
-			new Object[]{new Integer(-1),new Integer(5) }, DOMException.INDEX_SIZE_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "substringData", new Class[]{int.class, int.class}, 
-			new Object[]{new Integer(100),new Integer(5) }, DOMException.INDEX_SIZE_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(charData, "substringData", new Class[]{int.class, int.class}, 
-			new Object[]{new Integer(2),new Integer(-1) }, DOMException.INDEX_SIZE_ERR ));
-	
-
-//!! Throws NO_MODIFICATION_ALLOWED_ERR ******** 
-	Node node = document.getDocumentElement().getElementsByTagName("dBodyLevel24").item(0).getFirstChild().getChildNodes().item(0); // node gets ourEntityReference node's child text
-
-	OK &= Assertion.assert(tests.DOMExceptionsTest(node, "appendData", new Class[]{String.class}, 
-			new Object[]{"new data" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(node, "deleteData", new Class[]{int.class, int.class}, 
-			new Object[]{new Integer(5),new Integer(10) }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(node, "insertData", new Class[]{int.class, String.class}, 
-			new Object[]{new Integer(5),"Stuff inserted" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(node, "replaceData", new Class[]{int.class, int.class, String.class}, 
-			new Object[]{new Integer(5),new Integer(10),"Replacementstuff" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(node, "setData", new Class[]{String.class}, 
-			new Object[]{"New setdata stuff"}, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
-	
-		
-// For debugging*****		println("All CharacterData method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The CharacterData method calls listed above failed, all others worked correctly.*****");
-	charData.setData(resetData); // reset node to original data
-//	println("");
-}
-/**
- * This method tests ChildNodeList methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testChildNodeList(org.w3c.dom.Document document)
-{
-	
-	Node node, node2;
-	boolean OK = true;
-// For debugging*****	println("\n          testChildNodeList's outputs:\n");
-	node = document.getDocumentElement().getLastChild(); // node gets doc's testBody element
-	
-	if (!(node.getChildNodes().getLength()== 4))
-		OK = false;
-	node2 = node.getChildNodes().item(2);
-	if (! node2.getNodeName().equals("dBodyLevel23"))
-		OK = false;
-	
-// For debugging*****		println("All ChildNodeList method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The ChildNodeList method calls listed above failed, all others worked correctly.*****");		
-//	println("");
-}
-/**
- * This method tests Comment methods for the XML DOM implementation
- * version 1.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testComment(org.w3c.dom.Document document)
-{
-	Node node, node2;
-	boolean T = true;
-	boolean OK = true;
-// For debugging*****	println("\n          testComment's outputs:\n");
-	node = document.getDocumentElement().getElementsByTagName("dBodyLevel31").item(0).getFirstChild(); // node gets textNode11
-	node2 = node.cloneNode(T);
-	// Check nodes for equality, both their name and value or lack thereof
-	if (!(node.getNodeName().equals(node2.getNodeName()) && 		// Compares node names for equality
-	      (node.getNodeValue() != null && node2.getNodeValue() != null)     // Checks to make sure each node has a value node
-	    ?  node.getNodeValue().equals(node2.getNodeValue()) 		// If both have value nodes test those value nodes for equality
-	    : (node.getNodeValue() == null && node2.getNodeValue() == null)))	// If one node doesn't have a value node make sure both don't
-		//println("'cloneNode' did not clone the Comment node correctly");
-		OK = false;
-	// Deep clone test comparison is in testNode & testDocument
-	if (OK)
-// For debugging*****		println("All Comment method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The Comment method calls listed above failed, all others worked correctly.*****");
-//	println("");
-}
-/**
- * This method tests DeepNodeList methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testDeepNodeList(org.w3c.dom.Document document)
-{
-	
-	Node node, node2;
-	boolean OK = true;
-// For debugging*****	println("\n          testDeepNodeList's outputs:\n");
-	node = document.getLastChild().getLastChild(); // node gets docBody element
-	if (!(8 == ((Element) node).getElementsByTagName("*").getLength()))
-		{
-			System.out.println ("Warning!!! DeepNodeList's 'getLength' failed to work properly!");
-			OK = false;		
-		}
-	node2 = ((Element) node).getElementsByTagName("*").item(2); //This also runs through 'nextMatchingElementAfter"
-	if (! node2.getNodeName().equals("dBodyLevel32"))
-		{
-			System.out.println ("Warning!!! DeepNodeList's 'item' (or Element's 'getElementsBy TagName)failed to work properly!");
-			OK = false;		
-		}
-	node2 = document.getLastChild();
-	if (! ((Element) node2).getElementsByTagName("dTestBody").item(0).getNodeName().equals("dTestBody"))//This also runs through 'nextMatchingElementAfter"
-		{
-			System.out.println ("Warning!!! DeepNodeList's 'item' (or Element's 'getElementsBy TagName)failed to work properly!");
-			OK = false;		
-		}
-		
-	
-// For debugging*****		println("All DeepNodeList method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The DeepNodeList method calls listed above failed, all others worked correctly.*****");
-//	println("");
-}
-/**
- * This method tests Document methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- *
- **** ALL Document create methods are run in docBuilder except createAttribute which is in testAttribute**
- */
-public void testDocument(org.w3c.dom.Document document)
-{
-	DTest make = new DTest();
-	DocumentFragment docFragment, docFragment2;
-	Element newElement;
-	Node node, node2;
-	String[] elementNames =  {"dFirstElement", "dTestBody", "dBodyLevel21","dBodyLevel31","dBodyLevel32",
-				   "dBodyLevel22","dBodyLevel33","dBodyLevel34","dBodyLevel23","dBodyLevel24"};
-	String[] newElementNames = {"dFirstElement", "dTestBody", "dBodyLevel22","dBodyLevel33","dBodyLevel34","dBodyLevel23"};
-	boolean result;
-	boolean OK = true;
-// For debugging*****	println("\n          testDocument's outputs:\n ");
-	
-	DocumentType checkDocType =  make.createDocumentType(document,"testDocument1");
-	DocumentType docType = document.getDoctype();
-	if (! (checkDocType.getNodeName().equals(docType.getNodeName()) && 		// Compares node names for equality
-	      (checkDocType.getNodeValue() != null && docType.getNodeValue() != null)   // Checks to make sure each node has a value node
-	    ?  checkDocType.getNodeValue().equals(docType.getNodeValue()) 		// If both have value nodes test those value nodes for equality
-	    : (checkDocType.getNodeValue() == null && docType.getNodeValue() == null)))	// If one node doesn't have a value node make sure both don't
-	{
-		System.out.println("Warning!!! Document's 'getDocType method failed!" );
-		OK = false;
-	}
-		
-	Node rootElement = document.getLastChild();
-	if (! (rootElement.getNodeName().equals(document.getDocumentElement().getNodeName()) && 		// Compares node names for equality
-	      (rootElement.getNodeValue() != null && document.getDocumentElement().getNodeValue() != null)   // Checks to make sure each node has a value node
-	    ?  rootElement.getNodeValue().equals(document.getDocumentElement().getNodeValue()) 		// If both have value nodes test those value nodes for equality
-	    : (rootElement.getNodeValue() == null && document.getDocumentElement().getNodeValue() == null)))	// If one node doesn't have a value node make sure both don't
-	{
-		System.out.println("Warning!!! Document's 'getDocumentElement' method failed!" );
-		OK = false;
-	}
-	
-	NodeList docElements = document.getElementsByTagName("*");
-	int docSize = docElements.getLength();
-	int i;
-	for (i = 0; i < docSize; i++)
-	{
-		Node n = (Node) docElements.item(i);
-		if (! (elementNames[i].equals(n.getNodeName())))
-		{
-			System.out.println("Comparison of this document's elements failed at element number " + i + " : " + n.getNodeName());
-			OK = false;
-			break;
-		}
-	}
-	if (document.equals(document.getImplementation()))
-	{
-		System.out.println("Warning!!! Document's 'getImplementation' method failed!" );
-		OK = false;		
-	}
-		
-	newElement = document.createElement("NewElementTestsInsertBefore");
-	//	doc.insertBefore(newElement,null);//!! Throws a HIERARCHY_REQUEST_ERR	*******	
-	//	doc.removeChild(docElements.item(9));//!! Throws a NOT_FOUND_ERR  ********
-
-	docFragment = document.createDocumentFragment();
-	//Tests removeChild and stores removed branch for tree reconstruction
-	docFragment.appendChild(docElements.item(1).removeChild(docElements.item(9)));
-	docFragment2 = document.createDocumentFragment();
-	//Tests removeChild and stores removed branch for tree reconstruction
-	docFragment2.appendChild(docElements.item(1).removeChild(docElements.item(2)));
-	docSize = docElements.getLength();
-	for (i = 0; i < docSize; i++)
-	{
-		Node n = (Node) docElements.item(i);
-		if (! (newElementNames[i].equals(n.getNodeName())))
-		{
-			System.out.println("Comparison of new document's elements failed at element number " + i + " : " + n.getNodeName());
-			OK = false;
-			break;
-		}
-	}
-	docElements.item(1).insertBefore(docFragment, null); //Reattaches removed branch to restore tree to the original
-	docElements.item(1).insertBefore(docFragment2, docElements.item(2)); //Reattaches removed branch to restore tree to the original
-
-	//	println(docElements.item(2).getNodeName());
-
-	docSize = docElements.getLength();
-	for (i = 0; i < docSize; i++)
-	{
-		Node n = (Node) docElements.item(i);
-		if (! (elementNames[i].equals(n.getNodeName())))
-		{
-			System.out.println("Comparison of restored document's elements failed at element number " + i + " : " + n.getNodeName());
-			OK = false;
-			break;
-		}
-	}
-
-	DTest tests = new DTest();
-
-	
-//	Document z = tests.createDocument();
-//	tests.docBuilder(z, "z");
-
-//!! Throws WRONG_DOCUMENT_ERR **********
-//	OK &= Assertion.assert(tests.DOMExceptionsTest(z, "appendChild", new Class[]{Node.class}, new Object[]{doc.createComment("Test doc d comment")}, DOMException.HIERARCHY_REQUEST_ERR )); 
-		
-	//	z.appendChild(d.createComment("Test doc d comment"));// Tries to append z document with document d comment
-	//	d.getDocumentElement().appendChild(z.createElement("newZdocElement"));// Tries to append d document with document z Element
-	//	d.getLastChild().getLastChild().insertBefore(z.createElement("newZdocElement"),d.getLastChild().getLastChild().getFirstChild());// Tries to insert into d document with document z Element
-	//	d.replaceChild(z.createElement("newZdocElement"),d.getLastChild().getLastChild().getFirstChild());	// Tries to replace in d document with document z Element
-
-	//	doc.setNodeValue("This shouldn't work");//!! Throws a NO_MODIFICATION_ALLOWED_ERR ********
-	
-	node = document;
-	node2 = document.cloneNode(true);
-	result = treeCompare(node, node2); // Deep clone test comparison of document cloneNode
-	if (!result)
-	{
-		System.out.println("Warning!!! Deep clone of the document failed!");
-		OK = false;
-	}
-
-	// check on the ownerDocument of the cloned nodes
-	Document doc2 = (Document) node2;
-	Assertion.assert(doc2.getDocumentElement().getOwnerDocument() == doc2);
-
-	// Deep clone test comparison is also in testNode
-
-	// try adding a new element to the cloned document
-	node2 = doc2.createElement("foo");
-	doc2.getDocumentElement().appendChild(node2);
-	
-// For debugging*****		println("All Document method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The Document method calls listed above failed, all others worked correctly.*****");
-//	println("");
-}
-/**
- * This method tests DocumentFragment methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- *
- *
- ********This really isn't needed, only exists to throw NO_MODIFICATION_ALLOWED_ERR ********
- */
-public void testDocumentFragment(org.w3c.dom.Document document)
-{
-	boolean OK = true;
-// For debugging*****	println("\n          testDocumentFragment's outputs:\n");
-	DocumentFragment testDocFragment = document.createDocumentFragment();
-		
-	//	testDocFragment.setNodeValue("This is a document fragment!");//!! Throws a NO_MODIFICATION_ALLOWED_ERR ********
-	
-// For debugging*****		println("All DocumentFragment method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The DocumentFragment method calls listed above failed, all others worked correctly.*****");
-//	println("");
-}
-/**
- * This method tests DocumentType methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testDocumentType(org.w3c.dom.Document document)
-{
-	DTest test = new DTest();
-	DocumentType docType, holdDocType;
-	NamedNodeMap docEntityMap, docNotationMap;
-	Node node, node2;
-	String compare;
-	boolean OK = true;
-// For debugging*****	println("\n          testDocumentType's outputs:\n");
-	DocumentType newDocumentType =  test.createDocumentType(document, "TestDocument");
-	node = document.getFirstChild(); // node gets doc's docType node
-	node2 = node.cloneNode(true);
-	// Check nodes for equality, both their name and value or lack thereof
-	if (! (node.getNodeName().equals(node2.getNodeName()) && 	     // Compares node names for equality
-	      (node.getNodeValue() != null && node2.getNodeValue() != null)  // Checks to make sure each node has a value node
-	    ?  node.getNodeValue().equals(node2.getNodeValue()) 	     // If both have value nodes test those value nodes for equality
-	    : (node.getNodeValue() == null && node2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
-	{	
-		System.out.println("'cloneNode' did not clone the DocumentType node correctly");
-		OK = false;
-	}
-	 // Deep clone test comparison is in testNode & testDocument
-
-	docType = (DocumentType) document.getFirstChild();
-	compare = "ourEntityNode";
-	docEntityMap = docType.getEntities();
-	if (! compare.equals(docEntityMap.item(0).getNodeName()))
-	{
-		System.out.println("Warning!!! DocumentType's 'getEntities' failed!" );
-		OK = false;
-	}
-	docNotationMap = docType.getNotations();
-	compare = "ourNotationNode";
-	if (! compare.equals(docNotationMap.item(0).getNodeName()))
-	{
-		System.out.println("Warning!!! DocumentType's 'getNotations' failed!");
-		OK = false;
-	}
-	//	doc.appendChild(newDocumentTypeImpl);//!! Throws a HIERARCHY_REQUEST_ERR	*******	
-	holdDocType = (DocumentType) document.removeChild(document.getFirstChild()); //Tests removeChild and stores removed branch for tree reconstruction
-	document.insertBefore(newDocumentType, document.getDocumentElement());
-	//** Other aspects of insertBefore are tested in docBuilder through appendChild*
-
-	document.removeChild(document.getFirstChild()); //Removes newDocumentType for tree restoral
-	document.insertBefore(holdDocType, document.getFirstChild()); //Reattaches removed branch to restore tree to the original
-
-	
-// For debugging*****		println("All DocumentType method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The DocumentType method calls listed above failed, all others worked correctly.*****");
-//	println("");
-}
-/**
- * @author Philip W. Davis
- * @param document org.w3c.dom.Document
- */
-public void testDOMerrors(Document document) {
-
-	boolean OK = true;
-
-	DTest tests = new DTest();
-
-	OK &= Assertion.assert(tests.DOMExceptionsTest(document, "appendChild", new Class[]{Node.class}, new Object[]{testElementNode}, DOMException.HIERARCHY_REQUEST_ERR )); 
-	OK &= Assertion.assert(tests.DOMExceptionsTest(testTextNode, "appendChild", new Class[]{Node.class}, new Object[]{testTextNode}, DOMException.HIERARCHY_REQUEST_ERR )); 
-//	OK &= Assertion.assert(tests.DOMExceptionsTest(document, "insertBefore", new Class[]{Node.class, Node.class}, new Object[]{document.getElementsByTagName("docEntity").item(0), document.getElementsByTagName("docFirstElement").item(0)}, DOMException.HIERARCHY_REQUEST_ERR )); 
-//	OK &= Assertion.assert(tests.DOMExceptionsTest(document, "replaceChild", new Class[]{Node.class, Node.class}, new Object[]{document.getElementsByTagName("docCDATASection").item(0), document.getElementsByTagName("docFirstElement").item(0)}, DOMException.HIERARCHY_REQUEST_ERR )); 
-
-//	OK &= Assertion.assert(tests.DOMExceptionsTest(document.getElementsByTagName("docFirstElement").item(0), "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));	
-/*	OK &= Assertion.assert(tests.DOMExceptionsTest(docReferenceEntity, "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(docEntity, "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(document, "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(docDocType, "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(docDocFragment, "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(docNotation, "setNodeValue", new Class[]{String.class}, new Object[]{"This shouldn't work!" }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(docReferenceEntity, "appendChild", new Class[]{Node.class}, new Object[]{entityReferenceText2 }, DOMException.NO_MODIFICATION_ALLOWED_ERR ));
-
-
-	OK &= Assertion.assert(tests.DOMExceptionsTest(docBodyLevel32, "insertBefore", new Class[]{Node.class, Node.class}, new Object[]{docTextNode11,docBody }, DOMException.NOT_FOUND_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(docBodyLevel32, "removeChild", new Class[]{Node.class}, new Object[]{docFirstElement}, DOMException.NOT_FOUND_ERR ));
-	OK &= Assertion.assert(tests.DOMExceptionsTest(docBodyLevel32, "replaceChild", new Class[]{Node.class, Node.class}, new Object[]{docTextNode11,docFirstElement }, DOMException.NOT_FOUND_ERR ));
-*/
-
-//!! Throws a NOT_FOUND_ERR	********
-	 
-	 //	docBodyLevel32.getAttributes().removeNamedItem(testAttribute.getName()); 	16  // To test removeNamedItem
-	 
-
-
-
-
-
-
-
-
-
-
-
-	
-}
-/**
- * This method tests DOMImplementation methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testDOMImplementation(org.w3c.dom.Document document)
-{
-	
-	DOMImplementation implementation;
-	boolean result = false;
-	boolean OK = true;
-// For debugging*****	println("\n          testDOMImplementation's outputs:\n");
-	implementation = document.getImplementation(); //Uses getDOMImplementation to obtain implementation	
-
-	result = implementation.hasFeature("XML", "1.0");
-	if(!result)
-	{
-		System.out.println("Warning!!! DOMImplementation's 'hasFeature' that should be 'true' failed!");
-		OK = false;
-	}
-	
-	result = implementation.hasFeature("HTML", "4.0");
-	if(result)
-	{
-		System.out.println("Warning!!! DOMImplementation's 'hasFeature' that should be 'false' failed!");
-		OK = false;
-	}
-	
-	
-// For debugging*****		println("All DOMImplementation method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The DOMImplementation method calls listed above failed, all others worked correctly.*****");
-//	println("");
-}
-/**
- * This method tests Element methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testElement(org.w3c.dom.Document document)
-{
-	Attr attributeNode, newAttributeNode;
-	Element element, element2;
-	Node node, node2;
-	String attribute, compare;
-	String[] attributeCompare = {"AnotherFirstElementAttribute", "dFirstElement", "testAttribute"};
-	String[] elementNames =  {"dFirstElement", "dTestBody", "dBodyLevel21","dBodyLevel31","dBodyLevel32",
-				   "dBodyLevel22","dBodyLevel33","dBodyLevel34","dBodyLevel23","dBodyLevel24"};
-	String[] textCompare = {"dBodyLevel31'sChildTextNode11", "dBodyLevel31'sChildTextNode12", "dBodyLevel31'sChildTextNode13"};
-	NamedNodeMap nodeMap;
-	boolean OK = true;
-// For debugging*****	println("\n          testElement's outputs:\n");
-	node = document.getDocumentElement(); // node gets doc's firstElement
-	node2 = node.cloneNode(true);
-	// Check nodes for equality, both their name and value or lack thereof
-	if (!(node.getNodeName().equals(node2.getNodeName()) &&		    // Compares node names for equality
-	     (node.getNodeValue() != null && node2.getNodeValue() != null)  // Checks to make sure each node has a value node
-	    ? node.getNodeValue().equals(node2.getNodeValue())  	    // If both have value nodes test those value nodes for equality
-	    :(node.getNodeValue() == null && node2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
-	{	
-		System.out.println("'cloneNode' did not clone the Element node correctly");
-		OK = false;
-	}
-	// Deep clone test comparison is in testNode & testDocument
-
-	element = document.getDocumentElement(); // element gets doc's firstElement
-	compare = "";
-	attribute = element.getAttribute(document + "'s test attribute");
-	if (! compare.equals(element.getAttribute(document + "'s test attribute")))
-	{
-		System.out.println("Warning!!! Element's 'getAttribute' failed!");
-		OK = false;
-	}
-	
-	attributeNode = element.getAttributeNode(document + "FirstElement");
-	if(! (attributeNode == null))
-	{
-		System.out.println("Warning!!! Element's 'getAttributeNode' failed! It should have returned 'null' here!");
-		OK = false;
-	}
-	
-	newAttributeNode = document.createAttribute("AnotherFirstElementAttribute");
-	newAttributeNode.setValue("A new attribute which helps test calls in Element");
-	element.setAttributeNode(newAttributeNode);
-	nodeMap = element.getAttributes();
-	int size = nodeMap.getLength();
-	int k;
-	for (k = 0; k < size; k++)
-	{
-		Node n = (Node) nodeMap.item(k);
-		if (! (attributeCompare[k].equals(n.getNodeName())))
-		{
-			System.out.println("Warning!!! Comparison of firstElement's attributes failed at attribute #"+ (k+1) +" " + n.getNodeValue());
-			System.out.println("This failure can be a result of Element's 'setValue' and/or 'setAttributeNode' and/or 'getAttributes' failing.");
-			OK = false;
-			break;
-		}
-	//	println("firstElement's attribute number " + k + " : " + n.getNodeName());
-	}
-	NodeList docElements = document.getElementsByTagName("*");
-	int docSize = docElements.getLength();
-	int i;
-	for (i = 0; i < docSize; i++)
-	{
-		Node n = (Node) docElements.item(i);
-		if (! (elementNames[i].equals(n.getNodeName())))
-		{
-			System.out.println("Warning!!! Comparison of Element's 'getElementsByTagName' and/or 'item' failed at element number " 
-						+ i + " : " + n.getNodeName());
-			OK = false;
-			break;
-		}		
-	//	println("docElement's number " + i + " is: " + n.getNodeName());
-	}
-	element = (Element) document.getElementsByTagName("dBodyLevel21").item(0); // element gets Element test BodyLevel21 
-	element2 = (Element) document.getElementsByTagName("dBodyLevel31").item(0); // element2 gets Element test BodyLevel31 
-	NodeList text = ((Node) element2).getChildNodes();
-	int textSize = text.getLength();
-	int j;
-	for (j = 0; j < textSize; j++)
-	{
-		Node n = (Node) text.item(j);
-		if (! (textCompare[j].equals(n.getNodeValue())))
-		{
-			System.out.println("Warning!!! Comparison of original text nodes via Node 'getChildNodes' & NodeList 'item'"
-						+ "failed at text node: #" + j +" " + n.getNodeValue());
-			OK = false;
-			break;
-		}
-	//	println("Element testBodyLevel31's child text node " + j + " is: " + n.getNodeValue());
-	}
-	element = document.getDocumentElement(); // element gets doc's firstElement
-	element.normalize();		// Concatenates all adjacent text nodes in this element's subtree
-	NodeList text2 = ((Node) element2).getChildNodes();
-	compare = "dBodyLevel31'sChildTextNode11dBodyLevel31'sChildTextNode12dBodyLevel31'sChildTextNode13";
-	Node n = (Node) text2.item(0);
-		if (! (compare.equals(n.getNodeValue())))
-		{
-			System.out.println("Warning!!! Comparison of concatenated text nodes created by Element's 'normalize' failed!");
-			OK = false;
-		}
-	
-	element.setAttribute("FirstElementLastAttribute", "More attribute stuff for firstElement!!");
-	element.removeAttribute("FirstElementLastAttribute");
-	element.removeAttributeNode(newAttributeNode);
-
-	//	doc.getLastChild().setNodeValue("This shouldn't work");//!! Throws a NO_MODIFICATION_ALLOWED_ERR***
-	
-// For debugging*****		println("All Element method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The Element method calls listed above failed, all others worked correctly.*****");
-//	println("");
-}
-/**
- * This method tests Entity methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testEntity(org.w3c.dom.Document document)
-{
-	Entity entity;
-	Node node, node2;
-	boolean OK = true;
-	String compare;
-// For debugging*****	println("\n          testEntity's outputs:\n");
-	entity = (Entity) document.getDoctype().getEntities().getNamedItem("ourEntityNode");
-	node = entity;
-	node2 = entity.cloneNode(true);
-	// Check nodes for equality, both their name and value or lack thereof
-	if (!(node.getNodeName().equals(node2.getNodeName()) && 		// Compares node names for equality
-	     (node.getNodeValue() != null && node2.getNodeValue() != null) ?    // Checks to make sure each node has a value node
-	      node.getNodeValue().equals(node2.getNodeValue()) :		// If both have value nodes test those value nodes for equality
-	     (node.getNodeValue() == null && node2.getNodeValue() == null)))	// If one node doesn't have a value node make sure both don't
-	{	
-		System.out.println("Warning!!! 'cloneNode' did not clone the Entity node correctly");
-		OK = false;
-	}
-	// Deep clone test comparison is in testNode & testDocument
-
- 	((org.apache.xerces.dom.EntityImpl) entity).setNotationName("testNotationName");
-	compare = "testNotationName";
- 	if(! compare.equals(entity.getNotationName()))
-	{
-		System.out.println("Warning!!! Entity's 'setNotationName' and/or getNotationName' failed!");
-		OK = false;
-	}
- 	((org.apache.xerces.dom.EntityImpl) entity).setPublicId("testPublicId");
-	compare = "testPublicId";
- 	if(! compare.equals(entity.getPublicId()))
-	{
-		System.out.println("Warning!!! Entity's 'setPublicId' and/or getPublicId' failed!");
-		OK = false;
-	}	
- 	((org.apache.xerces.dom.EntityImpl) entity).setSystemId("testSystemId");
-	compare = "testSystemId";
- 	if(! compare.equals(entity.getSystemId()))
-	{
-		System.out.println("Warning!!! Entity's 'setSystemId' and/or getSystemId' failed!");
-		OK = false;
-	}		
-	//	entity.setNodeValue("This shouldn't work");//!! Throws a NO_MODIFICATION_ALLOWED_ERR ********
-	
-// For debugging*****		println("All Entity method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The Entity method calls listed above failed, all others worked correctly.*****");
-//	println("");
-}
-/**
- * This method tests EntityReference methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testEntityReference(org.w3c.dom.Document document)
-{
-	EntityReference entityReference;
-	Node node, node2;
-	boolean OK = true;
-// For debugging*****	println("\n          testEntityReference's outputs:\n");
-	entityReference = (EntityReference) document.getLastChild().getLastChild().getLastChild().getFirstChild();
-	node = entityReference;
-	node2 = node.cloneNode(true);
-	// Check nodes for equality, both their name and value or lack thereof
-	if (!(node.getNodeName().equals(node2.getNodeName()) && 	    // Compares node names for equality
-	     (node.getNodeValue() != null && node2.getNodeValue() != null)  // Checks to make sure each node has a value node
-	    ? node.getNodeValue().equals(node2.getNodeValue()) 		    // If both have value nodes test those value nodes for equality
-	    :(node.getNodeValue() == null && node2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
-	{	
-		System.out.println("'cloneNode' did not clone the EntityReference node correctly");
-		OK = false;
-	}
-	// Deep clone test comparison is in testNode & testDocument
-
-	//	entityReference.setNodeValue("This shouldn't work");//!! Throws a NO_MODIFICATION_ALLOWED_ERR ********
-	
-// For debugging*****		println("All EntityReference method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The EntityReference method calls listed above failed, all others worked correctly.*****");
-//	println("");
-}
-/**
- * This method tests Node methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- *
- *
- ********* This is only for a test of cloneNode "deep"*******
- ********* And for error tests*********
- */
-public void testNode(org.w3c.dom.Document document)
-{
-	Node node, node2;
-	boolean result;
-	boolean OK = true;
-// For debugging*****	println("\n          testNode's outputs:\n");
-	node = document.getDocumentElement();
-	node2 = node.cloneNode(true);
-	result = treeCompare(node, node2); // Deep clone test of cloneNode
-	if (result)
-	{
-		//println("'cloneNode' successfully cloned this whole node tree (deep)!");
-	}
-	else
-	{
-		System.out.println("'cloneNode' did not successfully clone this whole node tree (deep)!");
-		OK = false;	
-	}
-	//!! The following gives a did not clone successfully message*********
-	node = document.getDocumentElement();
-	node2 = node.getFirstChild();
-	result = treeCompare(node, node2);
-	if (!result)
-	{
-		//println("'cloneNode' did not successfully clone this whole node tree (deep)!");
-	}
-	else
-	{
-		System.out.println("'cloneNode' was supposed to fail here, either it or 'treeCompare' failed!!!");
-		OK = false;
-	}
-	// Deep clone test also in testDocument
-	
-// For debugging*****		println("All Node method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The Node method calls listed above failed, all others worked correctly.*****");	
-//	println("");
-}
-/**
- * This method tests Notation methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testNotation(org.w3c.dom.Document document)
-{
-	Node node, node2;
-	Notation notation;
-	boolean OK = true;
-	String compare;
-// For debugging*****	println("\n          testNotation's outputs:\n");
-	notation = (Notation) document.getDoctype().getNotations().getNamedItem("ourNotationNode");
-	node = notation;
-	node2 = notation.cloneNode(true);//*****?
-	// Check nodes for equality, both their name and value or lack thereof
-	if (!(node.getNodeName().equals(node2.getNodeName()) && 	    // Compares node names for equality
-	     (node.getNodeValue() != null && node2.getNodeValue() != null)  // Checks to make sure each node has a value node
-	    ? node.getNodeValue().equals(node2.getNodeValue()) 		    // If both have value nodes test those value nodes for equality
-	    :(node.getNodeValue() == null && node2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
-	{	
-		System.out.println("'cloneNode' did not clone the Notation node correctly");
-		OK = false;
-	}
-	// Deep clone test comparison is in testNode & testDocument
-
- 	((org.apache.xerces.dom.NotationImpl) notation).setPublicId("testPublicId");//*****?
-	compare = "testPublicId";
-	if (!compare.equals(notation.getPublicId()))
-	{
-		System.out.println("Warning!!! Notation's 'getPublicId' failed!");
-		OK = false;
-	}
- 	((org.apache.xerces.dom.NotationImpl) notation).setSystemId("testSystemId");//*****?
-	compare = "testSystemId";
-	if (! compare.equals(notation.getSystemId()))
-	{
-		System.out.println("Warning!!! Notation's 'getSystemId' failed!");
-		OK = false;
-	}
-	//	notation.setNodeValue("This shouldn't work");//!! Throws a NO_MODIFICATION_ALLOWED_ERR ********
-	
-// For debugging*****		println("All Notation method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The Notation method calls listed above failed, all others worked correctly.*****");
-//	println("");
-}
-/**
- * This method tests ProcessingInstruction methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testPI(org.w3c.dom.Document document)
-{
-	Node node, node2;
-	ProcessingInstruction pI, pI2;
-	String compare;
-	boolean OK = true;
-// For debugging*****	println("\n          testPI's outputs:\n");
-	pI = (ProcessingInstruction) document.getDocumentElement().getFirstChild();// Get doc's ProcessingInstruction
-	pI2 = (org.apache.xerces.dom.ProcessingInstructionImpl) pI.cloneNode(true);//*****?
-	// Check nodes for equality, both their name and value or lack thereof
-	if (!(pI.getNodeName().equals(pI2.getNodeName()) && 		// Compares node names for equality
-	     (pI.getNodeValue() != null && pI2.getNodeValue() != null)  // Checks to make sure each node has a value node
-	    ? pI.getNodeValue().equals(pI2.getNodeValue()) 		// If both have value nodes test those value nodes for equality
-	    :(pI.getNodeValue() == null && pI2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
-	{	
-		System.out.println("'cloneNode' did not clone the Entity node correctly");
-		OK = false;
-	}
-	// Deep clone test comparison is in testNode & testDocument
-	compare = "This is [#document: null]'s processing instruction";
-	if (! compare.equals(pI.getData()))
-	{
-		System.out.println("Warning!!! PI's 'getData' failed!");
-		OK = false;
-	}
-	
-	pI.setData("PI's reset data");
-	compare = "PI's reset data";
-	if (! compare.equals(pI.getData()))
-	{
-		System.out.println("Warning!!! PI's 'setData' failed!");
-		OK = false;
-	}	
-	compare = "dTargetProcessorChannel";
-	if (! compare.equals(pI.getTarget()))
-	{
-		System.out.println("Warning!!! PI's 'getTarget' failed!");
-		OK = false;
-	}	
-	
-// For debugging*****		println("All PI method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The PI method calls listed above failed, all others worked correctly.*****");
-	
-//	println("");
-}
-/**
- * This method tests Text methods for the XML DOM implementation
- * version 2.0 10/12/98
- * @param document org.w3c.dom.Document
- *
- * @author Philip W. Davis
- */
-public void testText(org.w3c.dom.Document document)
-{
-	Node node, node2;
-	Text text;
-	String compare;
-	boolean OK = true;
-// For debugging*****	println("\n          testText's outputs:\n");
-	node = document.getDocumentElement().getElementsByTagName("dBodyLevel31").item(0).getFirstChild(); // charData gets textNode11
-	text = (Text) node;
-	node2 = node.cloneNode(true);//*****?
-	// Check nodes for equality, both their name and value or lack thereof
-	if (!(node.getNodeName().equals(node2.getNodeName()) && 	    // Compares node names for equality
-	     (node.getNodeValue() != null && node2.getNodeValue() != null)  // Checks to make sure each node has a value node
-	    ? node.getNodeValue().equals(node2.getNodeValue()) 		    // If both have value nodes test those value nodes for equality
-	    :(node.getNodeValue() == null && node2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
-	{	
-		System.out.println("'cloneNode' did not clone the Text node correctly");
-		OK = false;
-	}
-	// Deep clone test comparison is in testNode & testDocument
-	text.splitText(25);
-	compare = "dBodyLevel31'sChildTextNo";	// Three original text nodes were concatenated by 'normalize' in testElement
-	if (! compare.equals(text.getNodeValue()))
-		{
-			System.out.println("First part of Text's split text failed!" );
-			OK = false;
-		}
-	compare = "de11dBodyLevel31'sChildTextNode12dBodyLevel31'sChildTextNode13";// Three original text nodes were concatenated by 'normalize' in testElement
-	if (! compare.equals(text.getNextSibling().getNodeValue()))
-		{
-			System.out.println("The second part of Text's split text failed!") ;
-			OK = false;	
-		}
-
-
-
-
-//************************************************* ERROR TESTS
-	DTest tests = new DTest();		
-	//!! Throws INDEX_SIZE_ERR ********************
-	//	text.splitText(-1);
-	//	text.splitText(100);
-	
-// For debugging*****		println("All Text method calls worked correctly.");
-	if (!OK)
-		System.out.println("\n*****The Text method calls listed above failed, all others worked correctly.*****");
-	
-//	println("");
-}
-/**
- * 
- * @param node org.w3c.dom.Node
- * @param node2 org.w3c.dom.Node
- *
- * @author Philip W. Davis
- */
-public boolean treeCompare(Node node, Node node2)
-{
-	boolean answer = true;
-		
-	Node kid, kid2;			// Check the subtree for equality
-	kid = node.getFirstChild();
-	kid2 = node2.getFirstChild();
-	if (kid != null && kid2 != null)
-	{
-		answer = treeCompare(kid, kid2);
-		if (!answer)
-			return answer;
-		else
-			if (kid.getNextSibling() != null && kid2.getNextSibling() != null)
-			{
-				while (kid.getNextSibling() != null && kid2.getNextSibling() != null)
-				{
-					answer = treeCompare(kid.getNextSibling(), kid2.getNextSibling());
-					if (!answer)
-						return answer;
-					else
-					{
-						kid = kid.getNextSibling();
-						kid2 = kid2.getNextSibling();
-					}
-				}
-			} else
-				if (!(kid.getNextSibling() == null && kid2.getNextSibling() == null))
-				{
-					return false;
-				}
-	} else
-		if (kid != kid2)
-		{
-			return false;
-		}
-
-	// Check nodes for equality, both their name and value or lack thereof
-	if (!(node.getNodeName().equals(node2.getNodeName()) &&		    // Compares node names for equality
-	     (node.getNodeValue() != null && node2.getNodeValue() != null)  // Checks to make sure each node has a value node
-	    ? node.getNodeValue().equals(node2.getNodeValue()) 		    // If both have value nodes test those value nodes for equality
-	    :(node.getNodeValue() == null && node2.getNodeValue() == null)))// If one node doesn't have a value node make sure both don't
-	{
-		return false;	// Return false if "any" of the above conditions are false
-	}
-	return answer;
-}
-}
diff --git a/tests/dom/Makefile b/tests/dom/Makefile
deleted file mode 100644
index 2d310d9..0000000
--- a/tests/dom/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-
-TARGETS= DTest.class
-
-DIRS = util mem range serialize events
-
-TOP = ../..
-include $(TOP)/src/Makefile.incl
-CLPATH := $(TOP)/tests;${CLPATH}
-
diff --git a/tests/dom/events/Makefile b/tests/dom/events/Makefile
deleted file mode 100644
index fe34f2a..0000000
--- a/tests/dom/events/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-
-TARGETS= Test.class
-
-DIRS =
-
-TOP = ../../..
-include $(TOP)/src/Makefile.incl
diff --git a/tests/dom/events/Test.java b/tests/dom/events/Test.java
deleted file mode 100644
index 5bc0f9c..0000000
--- a/tests/dom/events/Test.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/* $Id$ */
-/*
- * The Apache Software License, Version 1.1
- * 
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- * 
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- * 
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache\@apache.org.
- * 
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- * 
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- * 
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation, and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.ibm.com .  For more information
- * on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package dom.events;
-
-import org.w3c.dom.*;
-import org.w3c.dom.events.*;
-
-public class Test
-{
-    EventReporter sharedReporter=new EventReporter();
-    
-    public static void main(String[] args)
-    {
-        Test met=new Test();
-        met.runTest();
-    }
-
-    void runTest()
-    {
-        Document doc=new org.apache.xerces.dom.DocumentImpl();
-        reportAllMutations(doc);
-        
-        Element root=addNoisyElement(doc,doc,0);
-        Element e=null;
-        int i;
-        
-        // Individual nodes
-        e=addNoisyElement(doc,root,0);
-        Attr a=addNoisyAttr(doc,e,0);
-        a.setNodeValue("Updated A0 of E0, prepare to be acidulated.");
-        NamedNodeMap nnm=e.getAttributes();
-        nnm.removeNamedItem(a.getName());
-        nnm.setNamedItem(a);
-        
-        // InsertedInto/RemovedFrom tests.
-        // ***** These do not currently cross the Attr/Element barrier.
-        // DOM spec is pretty clear on that, but this may not be the intent.
-        System.out.println("\nAdd/remove a preconstructed tree; tests AddedToDocument\n");
-        sharedReporter.off();
-        Element lateAdd=doc.createElement("lateAdd");
-        reportAllMutations(lateAdd);
-        e=lateAdd;
-        for(i=0;i<2;++i)
-        {
-            e=addNoisyElement(doc,e,i);
-            addNoisyAttr(doc,e,i);
-        }
-        sharedReporter.on();
-        root.appendChild(lateAdd);
-        root.removeChild(lateAdd);
-
-        System.out.println("\nReplace a preconstructed tree; tests AddedToDocument\n");
-
-        sharedReporter.off();
-        Node e0=root.replaceChild(lateAdd,root.getFirstChild());
-        sharedReporter.on();
-        root.replaceChild(e0,lateAdd);
-        
-
-        System.out.println("Done");
-    }
-    
-    Element addNoisyElement(Document doc,Node parent,int index)
-    {
-        String nodeName="Root";
-        if(parent!=doc)
-            nodeName=parent.getNodeName()+"_E"+index;
-        Element e=doc.createElement(nodeName);
-        reportAllMutations(e);
-        parent.appendChild(e);
-        return e;
-    }
-
-    Attr addNoisyAttr(Document doc,Element parent,int index)
-    {
-        String attrName=parent.getNodeName()+"_A"+index;
-        Attr a=doc.createAttribute(attrName);
-        reportAllMutations(a);
-        a.setNodeValue("Initialized A"+index+" of "+parent.getNodeName());
-        parent.setAttributeNode(a);
-        return a;
-    }
-    
-    void reportAllMutations(Node n)
-    {
-        String[] evtNames={
-            "DOMSubtreeModified","DOMAttrModified","DOMCharacterDataModified",
-            "DOMNodeInserted","DOMNodeRemoved",
-            "DOMNodeInsertedIntoDocument","DOMNodeRemovedFromDocument",
-            };
-            
-        EventTarget t=(EventTarget)n;
-        
-        for(int i=evtNames.length-1;
-            i>=0;
-            --i)
-        {
-            t.addEventListener(evtNames[i], sharedReporter, true);
-            t.addEventListener(evtNames[i], sharedReporter, false);
-        }
-
-    }
-}
-
-class EventReporter implements EventListener
-{
-    boolean silent=false; // Toggle this to mask reports you don't care about
-    int count=0;
-    String[] phasename={"?","BUBBLING","CAPTURING","AT_TARGET","?"};
-    
-    public void on()
-    {
-        System.out.println("\nEventReporter awakened:\n");
-        silent=false;
-    }
-    public void off()
-    {
-        System.out.println("\nEventReporter muted\n");
-        silent=true;
-    }
-    
-    public void handleEvent(Event evt)
-    {
-        ++count;
-        if(silent)
-            return;
-            
-        System.out.print("EVT "+count+": '"+
-            evt.getType()+
-            "' listener '"+(evt.getCurrentNode()).getNodeName()+
-            "' target '"+((Node)evt.getTarget()).getNodeName()+
-            "' while "+phasename[evt.getEventPhase()] +
-            "... ");
-        if(evt.getBubbles()) System.out.print("will bubble");
-        if(evt.getCancelable()) System.out.print("can cancel");
-        System.out.print("\n");
-        if(evt instanceof MutationEvent)
-        {
-            MutationEvent me=(MutationEvent)evt;
-            System.out.print("\t");
-            if(me.getRelatedNode()!=null)
-                System.out.print(" relatedNode='"+me.getRelatedNode()+"'");
-            if(me.getAttrName()!=null)
-                System.out.print(" attrName='"+me.getAttrName()+"'");
-            System.out.print("\n");
-            if(me.getPrevValue()!=null)
-                System.out.println("\t prevValue='"+me.getPrevValue()+"'");
-            if(me.getNewValue()!=null)
-                System.out.println("\t newValue='"+me.getNewValue()+"'");
-        }
-    }
-}
diff --git a/tests/dom/mem/Makefile b/tests/dom/mem/Makefile
deleted file mode 100644
index 90db3b1..0000000
--- a/tests/dom/mem/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-
-TARGETS= Test.class
-
-DIRS =
-
-TOP = ../../..
-include $(TOP)/src/Makefile.incl
-CLPATH := $(TOP)/tests;${CLPATH}
-
diff --git a/tests/dom/mem/Test.java b/tests/dom/mem/Test.java
deleted file mode 100644
index 8b8128c..0000000
--- a/tests/dom/mem/Test.java
+++ /dev/null
@@ -1,1216 +0,0 @@
-/* $Id$ */
-/*
- * The Apache Software License, Version 1.1
- * 
- * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights 
- * reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- * 
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- * 
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache\@apache.org.
- * 
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- * 
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- * 
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation, and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.ibm.com .  For more information
- * on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-//
-//  Various DOM tests.
-//     Contents include
-//       1.  Basic functionality for DOMString
-//       2.  Regression tests for bugs fixed.
-//     All individual are wrapped in a memory leak checker.
-//
-//     This is NOT a complete test of DOM functionality.
-//
-
-package dom.mem;
-import org.w3c.dom.*;
-import org.apache.xerces.dom.DocumentImpl;
-import org.apache.xerces.dom.DOMImplementationImpl;
-import org.apache.xerces.dom.NotationImpl;
-import java.lang.reflect.*;
-import dom.util.Assertion;
-
-public class Test {
-
-    /**
-     * version 3.0 01/25/99
-     * 
-     * @return boolean
-     * @param node java.lang.Object
-     * @param mNameIndex int
-     * @param signatureIndex int
-     * @param parameters java.lang.Object[]
-     * @param code short
-     *
-     * @author Philip W. Davis
-     */
-    public static boolean DOMExceptionsTest(Object node,
-					    String methodName,
-					    Class[] methodSignature,
-					    Object[] parameters,
-					    short code)
-    {
-	boolean asExpected = false;
-	Method method;
-
-	try {
-	    method = node.getClass().getMethod(methodName,methodSignature);
-	    method.invoke(node, parameters);
-	} catch(InvocationTargetException exc) {
-	    Throwable realE = exc.getTargetException(); 
-	    if(realE instanceof DOMException) {
-		asExpected = (((DOMException)realE).code== code);
-		if(!asExpected)
-		    System.out.println("Wrong DOMException(" +
-				       ((DOMException)realE).code + ")");
-	    } else {
-		System.out.println("Wrong Exception (" + code + ")");
-	    }
-	    if(!asExpected) {
-		System.out.println("Expected DOMException (" +
-				   code + ") not thrown");
-	    }
-	} catch(Exception exc) {
-	    System.out.println("test invocation failure (" + exc + ")");
-	}
-	return (asExpected);
-    }
-
-    public static void main(String argv[])
-    {
-    System.out.print("DOM Memory Test.\n");
-
-    //
-    //  Test Doc01      Create a new empty document
-    //
-    {
-        Document    doc;
-        doc = new DocumentImpl();
-    }
-    
-
-    //
-    //  Test Doc02      Create one of each kind of node using the
-    //                  document createXXX methods.
-    //                  Watch for memory leaks.
-    //
-    {
-        //  Do all operations in a preconditioning step, to force the
-        //  creation of implementation objects that are set up on first use.
-        //  Don't watch for leaks in this block (no  / )
-        Document doc = new DocumentImpl();
-        Element     el = doc.createElement("Doc02Element");
-        DocumentFragment frag = doc.createDocumentFragment ();
-        Text  text = doc.createTextNode("Doc02TextNode");
-        Comment comment = doc.createComment("Doc02Comment");
-        CDATASection  cdataSec = doc.createCDATASection("Doc02CDataSection");
-        DocumentType  docType = doc.getImplementation().createDocumentType("Doc02DocumentType", null, null);
-        Notation notation = ((DocumentImpl) doc).createNotation("Doc02Notation");
-        ProcessingInstruction pi = doc.createProcessingInstruction("Doc02PITarget",
-                                    "Doc02PIData");
-        NodeList    nodeList = doc.getElementsByTagName("*");
-    }
-
-
-    
-    {
-        Document doc = new DocumentImpl();
-        Element     el = doc.createElement("Doc02Element");
-    }
-    
-
-    
-    {
-        Document    doc = new DocumentImpl();
-        DocumentFragment frag = doc.createDocumentFragment ();
-    };
-    
-
-
-    
-    {
-        Document doc = new DocumentImpl();
-        Element     el = doc.createElement("Doc02Element");
-    }
-    
-
-    
-    {
-        Document doc = new DocumentImpl();
-        Text  text = doc.createTextNode("Doc02TextNode");
-    }
-    
-
-    
-    {
-        Document doc = new DocumentImpl();
-        Comment comment = doc.createComment("Doc02Comment");
-    }
-    
-
-    
-    {
-        Document doc = new DocumentImpl();
-        CDATASection  cdataSec = doc.createCDATASection("Doc02CDataSection");
-    }
-    
-
-
-    
-    {
-        Document doc = new DocumentImpl();
-        DocumentType  docType = doc.getImplementation().createDocumentType("Doc02DocumentType", null, null);
-    }
-    
-
-
-    
-    {
-        Document doc = new DocumentImpl();
-        Notation notation = ((DocumentImpl)doc).createNotation("Doc02Notation");
-    }
-    
-
-
-    
-    {
-        Document doc = new DocumentImpl();
-        ProcessingInstruction pi = doc.createProcessingInstruction("Doc02PITarget",
-                                    "Doc02PIData");
-    }
-    
-
-    
-    {
-        Document doc = new DocumentImpl();
-        Attr  attribute = doc.createAttribute("Doc02Attribute");
-    }
-    
-
-
-    
-    {
-        Document doc = new DocumentImpl();
-        EntityReference  er = doc.createEntityReference("Doc02EntityReference");
-    }
-    
-
-    
-    {
-        Document doc = new DocumentImpl();
-        NodeList    nodeList = doc.getElementsByTagName("*");
-    }
-    
-
-    
-    //
-    //  Doc03 - Create a small document tree
-    //
-    
-    {
-        Document    doc = new DocumentImpl();
-        Element     rootEl = doc.createElement("Doc03RootElement");
-        doc.appendChild(rootEl);
-        Text        textNode = doc.createTextNode("Doc03 text stuff");
-        rootEl.appendChild(textNode);
-
-        NodeList    nodeList = doc.getElementsByTagName("*");
-    };
-    
-
-
-    //
-    //  Attr01
-    //
-    {
-        Document    doc = new DocumentImpl();
-        Element     rootEl  = doc.createElement("RootElement");
-        doc.appendChild(rootEl);
-        {
-            Attr        attr01  = doc.createAttribute("Attr01");
-            rootEl.setAttributeNode(attr01);
-        }
-        
-        
-        {
-            Attr attr02 = doc.createAttribute("Attr01");
-            rootEl.setAttributeNode(attr02);  
-        }
-        
-    };
-
-    //
-    //  Attr02
-    //
-    
-    {
-        Document    doc = new DocumentImpl();
-        Element     rootEl  = doc.createElement("RootElement");
-        doc.appendChild(rootEl);
-        Attr        attr01  = doc.createAttribute("Attr02");
-        rootEl.setAttributeNode(attr01);
-        Attr        attr02 = doc.createAttribute("Attr02");
-        rootEl.setAttributeNode(attr02);  
-    }
-    
-
-
-    //
-    //  Attr03
-    //
-    
-    {
-        Document    doc = new DocumentImpl();
-        Element     rootEl  = doc.createElement("RootElement");
-        doc.appendChild(rootEl);
-        Attr        attr01  = doc.createAttribute("Attr03");
-        rootEl.setAttributeNode(attr01);
-
-        attr01.setValue("Attr03Value1");
-        attr01.setValue("Attr03Value2");
-    }
-    
-
-
-
-    //
-    //  Text01
-    //
-    
-    {
-        Document    doc = new DocumentImpl();
-        Element     rootEl  = doc.createElement("RootElement");
-        doc.appendChild(rootEl);
-
-
-        Text        txt1 = doc.createTextNode("Hello Goodbye");
-        rootEl.appendChild(txt1);
-
-        txt1.splitText(6);
-        rootEl.normalize();
-
-    }
-    
-
-
-    //
-    //  Notation01
-    //
-    
-    { 
-	/*
-        DOMImplementation impl = DOMImplementationImpl.getDOMImplementation();
-        DocumentType    dt  =
-	  impl.createDocumentType("DocType_for_Notation01", null, null, null);
-        doc.appendChild(dt);
-
-
-        NamedNodeMap notationMap = dt.getNotations();
-        Notation    nt1 = ((DocumentImpl) doc).createNotation("Notation01");
-        ((NotationImpl) nt1).setPublicId("Notation01PublicId");
-        notationMap.setNamedItem (nt1);
-        Notation    nt2 = (Notation)notationMap.getNamedItem("Notation01");
-        Assertion.assert(nt1==nt2);
-        nt2 = new NotationImpl((DocumentImpl)doc, null);
-        nt1 = null;
-        nt2 = (Notation)notationMap.getNamedItem("Notation01");
-      
-    */
-    }
-    
-
-
-    //
-    //  NamedNodeMap01 - comparison operators.
-    //
-    
-    {
-        NamedNodeMap    nnm = null;
-        Assertion.assert(nnm == null);
-
-        Document        doc = new DocumentImpl();
-        nnm = doc.getAttributes();    // Should be null, because node type
-                                      //   is not Element.
-        Assertion.assert(nnm == null);
-        Assertion.assert(!(nnm != null));
-
-        Element el = doc.createElement("NamedNodeMap01");
-        NamedNodeMap nnm2 = el.getAttributes();    // Should be an empty, but non-null map.
-        Assertion.assert(nnm2 != null);
-        Assertion.assert(nnm != nnm2);
-        nnm = nnm2;
-        Assertion.assert(nnm == nnm2);
-    }
-    
-
-
-    //
-    //  importNode quick test
-    //
-    
-    {
-        Document    doc1 = new DocumentImpl();
-        Document    doc2 = new DocumentImpl();
-        
-        Element     el1  = doc1.createElement("abc");
-        doc1.appendChild(el1);
-        Assertion.assert(el1.getParentNode() != null);
-        el1.setAttribute("foo", "foovalue");
-        Node        el2  = doc2.importNode(el1, true);
-        Assertion.assert(el2.getParentNode() == null);
-        String       tagName = el2.getNodeName();
-        Assertion.equals(tagName, "abc");
-        Assertion.assert(el2.getOwnerDocument() == doc2);
-        Assertion.equals(((Element) el2).getAttribute("foo"), "foovalue");
-        Assertion.assert(doc1 != doc2);
-    }
-    
-
-    //
-    //  getLength() tests.  Both Node CharacterData and NodeList implement
-    //                  getLength().  Early versions of the DOM had a clash
-    //                  between the two, originating in the implementation class
-    //                  hirearchy, which has NodeList as a (distant) base class
-    //                  of CharacterData.  This is a regression test to verify
-    //                  that the problem stays fixed.
-    //
-    
-    {
-        Document     doc = new DocumentImpl();
-        Text          tx = doc.createTextNode("Hello");
-        Element       el = doc.createElement("abc");
-        el.appendChild(tx);
-
-        int     textLength = tx.getLength();
-        Assertion.assert(textLength == 5);
-
-        NodeList      nl = tx.getChildNodes();
-        int      nodeListLen = nl.getLength();
-        Assertion.assert(nodeListLen == 0);
-
-        nl = el.getChildNodes();
-        nodeListLen = nl.getLength();
-        Assertion.assert(nodeListLen == 1);
-    }
-
-
-    //
-    //  NodeList - comparison operators, basic operation.
-    //
-    
-    {
-        NodeList    nl = null;
-        NodeList    nl2 = null;
-        Assertion.assert(nl == null);
-        Assertion.assert(!(nl != null));
-        Assertion.assert(nl == nl2);
-
-        Document        doc = new DocumentImpl();
-        nl = doc.getChildNodes();    // Should be non-null, but empty
-
-        Assertion.assert(nl != null);
-        int len = nl.getLength();
-        Assertion.assert(len == 0);
-
-        Element el = doc.createElement("NodeList01");
-        doc.appendChild(el);
-        len = nl.getLength();
-        Assertion.assert(len == 1);
-        Assertion.assert(nl != nl2);
-        nl2 = nl;
-        Assertion.assert(nl == nl2);
-    }
-    
-
-
- 
-    //
-    //  Name validity checking.
-    //
-    
-    {
-         Document        doc = new DocumentImpl();
-         Assertion.assert(DOMExceptionsTest(doc, "createElement",
-					  new Class[]{String.class},
-					  new Object[]{"!@@ bad element name"},
-					  DOMException.INVALID_CHARACTER_ERR));
-    }
-    
-
-
-    //
-    //  Assignment ops return value
-    //
-    
-    {
-        Document        doc = new DocumentImpl();
-        Element el = doc.createElement("NodeList01");
-        doc.appendChild(el);
-        
-        Element n1, n2, n3;
-        
-        n1 = n2 = n3 = el;
-        Assertion.assert(n1 == n2);
-        Assertion.assert(n1 == n3);
-        Assertion.assert(n1 == el);
-        Assertion.assert(n1 != null);
-        n1 = n2 = n3 = null;
-        Assertion.assert(n1 == null);
-    }
-    
-
-
-    //
-    //  Cloning of a node with attributes. Regression test for a ref counting 
-    //  bug in attributes of cloned nodes that occured when the "owned" flag
-    //  was not set in the clone.
-    //
-    
-    {
-        Document    doc = new DocumentImpl();
-        Element     root = doc.createElement("CTestRoot");
-        root.setAttribute("CTestAttr", "CTestAttrValue");
-
-        String s = root.getAttribute("CTestAttr");
-        Assertion.equals(s, "CTestAttrValue");
-
-        Element     cloned = (Element)root.cloneNode(true);
-        Attr a = cloned.getAttributeNode("CTestAttr");
-        Assertion.assert(a != null);
-        s = a.getValue();
-        Assertion.equals(s, "CTestAttrValue");
-        a = null;
-
-        a = cloned.getAttributeNode("CTestAttr");
-        Assertion.assert(a != null);
-        s = a.getValue();
-        Assertion.equals(s, "CTestAttrValue");
-
-    }
-    
-
-
-    //
-    //  DOM Level 2 tests.  These should be split out as a separate test.
-    //
-
-
-    //
-    // hasFeature.  The set of supported options tested here is for Xerces 1.1
-    //
-    
-    {
-        DOMImplementation  impl = DOMImplementationImpl.getDOMImplementation();
-        Assertion.assert(impl.hasFeature("XML", "2.0")    == true);
-        Assertion.assert(impl.hasFeature("XML", null)       == true);
-        //  We also support 1.0
-        Assertion.assert(impl.hasFeature("XML", "1.0")    == true);
-        Assertion.assert(impl.hasFeature("XML", "3.0")    == false);
-        Assertion.assert(impl.hasFeature("Traversal", null) == true);
-
-
-        Assertion.assert(impl.hasFeature("HTML", null)           == false);
-        Assertion.assert(impl.hasFeature("Views", null)          == false);
-        Assertion.assert(impl.hasFeature("StyleSheets", null)    == false);
-        Assertion.assert(impl.hasFeature("CSS", null)            == false);
-        Assertion.assert(impl.hasFeature("CSS2", null)           == false);
-        Assertion.assert(impl.hasFeature("Events", null)         == true);
-        Assertion.assert(impl.hasFeature("UIEvents", null)       == false);
-        Assertion.assert(impl.hasFeature("MouseEvents", null)    == false);
-        Assertion.assert(impl.hasFeature("MutationEvents", null) == true);
-        Assertion.assert(impl.hasFeature("HTMLEvents", null)     == false);
-        Assertion.assert(impl.hasFeature("Range", null)          == false);
-    }
-    
-
-
-    //
-    // CreateDocumentType
-    //
-    
-    {
-        DOMImplementation impl = DOMImplementationImpl.getDOMImplementation();
-        
-        String qName = "foo:docName";
-        String pubId = "pubId";
-        String sysId = "http://sysId";
-        
-        DocumentType dt = impl.createDocumentType(qName, pubId, sysId);
-        
-        Assertion.assert(dt != null);
-        Assertion.assert(dt.getNodeType() == Node.DOCUMENT_TYPE_NODE);
-        Assertion.equals(dt.getNodeName(), qName);
-        Assertion.assert(dt.getNamespaceURI() == null);
-        Assertion.assert(dt.getPrefix() == null);
-        Assertion.assert(dt.getLocalName() == null);
-        Assertion.equals(dt.getPublicId(), pubId);
-        Assertion.equals(dt.getSystemId(), sysId);
-        Assertion.assert(dt.getInternalSubset() == null);
-        Assertion.assert(dt.getOwnerDocument() == null);
-        
-        NamedNodeMap nnm = dt.getEntities();
-        Assertion.assert(nnm.getLength() == 0);
-        nnm = dt.getNotations();
-        Assertion.assert(nnm.getLength() == 0);
-
-        //
-        // Qualified name without prefix should also work.
-        //
-        qName = "docName";
-        dt = impl.createDocumentType(qName, pubId, sysId);
-
-        Assertion.assert(dt != null);
-        Assertion.assert(dt.getNodeType() == Node.DOCUMENT_TYPE_NODE);
-        Assertion.equals(dt.getNodeName(), qName);
-        Assertion.assert(dt.getNamespaceURI() == null);
-        Assertion.assert(dt.getPrefix() == null);
-        Assertion.assert(dt.getLocalName() == null);
-        Assertion.equals(dt.getPublicId(), pubId);
-        Assertion.equals(dt.getSystemId(), sysId);
-        Assertion.assert(dt.getInternalSubset() == null);
-        Assertion.assert(dt.getOwnerDocument() == null);
-
-        // Creating a DocumentType with invalid or malformed qName should fail.
-        Assertion.assert(DOMExceptionsTest(impl, "createDocumentType",
-			new Class[]{String.class, String.class, String.class},
-			new Object[]{"<docName", pubId, sysId},
-			DOMException.INVALID_CHARACTER_ERR));     
-        Assertion.assert(DOMExceptionsTest(impl, "createDocumentType",
-			new Class[]{String.class, String.class, String.class},
-			new Object[]{":docName", pubId, sysId},
-			DOMException.NAMESPACE_ERR));     
-        Assertion.assert(DOMExceptionsTest(impl, "createDocumentType",
-			new Class[]{String.class, String.class, String.class},
-			new Object[]{"docName:", pubId, sysId},
-			DOMException.NAMESPACE_ERR));     
-        Assertion.assert(DOMExceptionsTest(impl, "createDocumentType",
-			new Class[]{String.class, String.class, String.class},
-			new Object[]{"<doc::Name", pubId, sysId},
-			DOMException.INVALID_CHARACTER_ERR));     
-        Assertion.assert(DOMExceptionsTest(impl, "createDocumentType",
-			new Class[]{String.class, String.class, String.class},
-			new Object[]{"<doc:N:ame", pubId, sysId},
-			DOMException.INVALID_CHARACTER_ERR));     
-    }
-
-    //
-    //  DOMImplementation.CreateDocument
-    //
-    
-    {
-        DOMImplementation impl = DOMImplementationImpl.getDOMImplementation();
-        
-        String qName = "foo:docName";
-        String pubId = "pubId";
-        String sysId = "http://sysId";
-        
-        DocumentType dt = impl.createDocumentType(qName, pubId, sysId);
-        
-        String docNSURI = "http://document.namespace";
-        Document doc = impl.createDocument(docNSURI, qName, dt);
-
-        Assertion.assert(dt.getOwnerDocument() == doc);
-        Assertion.assert(doc.getOwnerDocument() == null);
-
-        Assertion.assert(doc.getNodeType() == Node.DOCUMENT_NODE);
-        Assertion.assert(doc.getDoctype() == dt);
-        Assertion.equals(doc.getNodeName(), "#document");
-        Assertion.assert(doc.getNodeValue() == null);
-
-        Element el = doc.getDocumentElement();
-
-        Assertion.equals(el.getLocalName(), "docName");
-        Assertion.equals(el.getNamespaceURI(), docNSURI);
-        Assertion.equals(el.getNodeName(), qName);
-        Assertion.assert(el.getOwnerDocument() == doc);
-        Assertion.assert(el.getParentNode() == doc);
-        Assertion.equals(el.getPrefix(), "foo");
-        Assertion.equals(el.getTagName(), qName);
-        Assertion.assert(el.hasChildNodes() == false);
-
-        //
-        // Creating a second document with the same docType object should fail.
-        //
-        Assertion.assert(DOMExceptionsTest(impl, "createDocument",
-					   new Class[]{String.class,
-						       String.class,
-						       DocumentType.class},
-					   new Object[]{docNSURI, qName, dt},
-					   DOMException.WRONG_DOCUMENT_ERR));
-
-        // Namespace tests of createDocument are covered by createElementNS below
-    }
-    
-    
-    //
-    //  CreateElementNS methods
-    //
-    
-    {
-        
-        // Set up an initial (root element only) document.
-        // 
-        DOMImplementation impl = DOMImplementationImpl.getDOMImplementation();
-        
-        String qName = "foo:docName";
-        String pubId = "pubId";
-        String sysId = "http://sysId";
-        DocumentType dt = impl.createDocumentType(qName, pubId, sysId);
-        
-        String docNSURI = "http://document.namespace";
-	Document doc = impl.createDocument(docNSURI, qName, dt);
-        Element rootEl = doc.getDocumentElement();
-
-        //
-        // CreateElementNS
-        //
-        Element ela = doc.createElementNS("http://nsa", "a:ela");  // prefix and URI
-        Element elb = doc.createElementNS("http://nsb", "elb");    //  URI, no prefix.
-        Element elc = doc.createElementNS(null, "elc");              // No URI, no prefix.
-
-        rootEl.appendChild(ela);
-        rootEl.appendChild(elb);
-        rootEl.appendChild(elc);
-
-        Assertion.equals(ela.getNodeName(), "a:ela");
-        Assertion.equals(ela.getNamespaceURI(), "http://nsa");
-        Assertion.equals(ela.getPrefix(), "a");
-        Assertion.equals(ela.getLocalName(), "ela");
-        Assertion.equals(ela.getTagName(), "a:ela");
-
-        Assertion.equals(elb.getNodeName(), "elb");
-        Assertion.equals(elb.getNamespaceURI(), "http://nsb");
-        Assertion.assert(elb.getPrefix() == null);
-        Assertion.equals(elb.getLocalName(), "elb");
-        Assertion.equals(elb.getTagName(), "elb");
-
-        Assertion.equals(elc.getNodeName(), "elc");
-        Assertion.assert(elc.getNamespaceURI() == null);
-        Assertion.assert(elc.getPrefix() ==  null);
-        Assertion.equals(elc.getLocalName(), "elc");
-        Assertion.equals(elc.getTagName(), "elc");
-
-        // Badly formed qualified name
-	Assertion.assert(DOMExceptionsTest(doc, "createElementNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", "<a"},
-				      DOMException.NAMESPACE_ERR));
-	Assertion.assert(DOMExceptionsTest(doc, "createElementNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", ":a"},
-				      DOMException.NAMESPACE_ERR));
-	Assertion.assert(DOMExceptionsTest(doc, "createElementNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", "a:"},
-				      DOMException.NAMESPACE_ERR));
-	Assertion.assert(DOMExceptionsTest(doc, "createElementNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", "a::a"},
-				      DOMException.NAMESPACE_ERR));
-	Assertion.assert(DOMExceptionsTest(doc, "createElementNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", "a:a:a"},
-				      DOMException.NAMESPACE_ERR));
-
-        // xml:a must have namespaceURI == "http://www.w3.org/XML/1998/namespace"
-	String xmlURI = "http://www.w3.org/XML/1998/namespace";
-	Assertion.equals(doc.createElementNS(xmlURI, "xml:a").getNamespaceURI(), xmlURI);
-	Assertion.assert(DOMExceptionsTest(doc, "createElementNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", "xml:a"},
-				      DOMException.NAMESPACE_ERR));
-	Assertion.assert(DOMExceptionsTest(doc, "createElementNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"", "xml:a"},
-				      DOMException.NAMESPACE_ERR));
-	Assertion.assert(DOMExceptionsTest(doc, "createElementNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{null, "xml:a"},
-				      DOMException.NAMESPACE_ERR));
-
-        //unlike Attribute, xmlns (no different from foo) can have any namespaceURI for Element
-        Assertion.equals(doc.createElementNS("http://nsa", "xmlns").getNamespaceURI(), "http://nsa");
-        Assertion.equals(doc.createElementNS(xmlURI, "xmlns").getNamespaceURI(), xmlURI);
-        Assertion.equals(doc.createElementNS("", "xmlns").getNamespaceURI(), "");
-        Assertion.assert(doc.createElementNS(null, "xmlns").getNamespaceURI() == null);
-
-        //unlike Attribute, xmlns:a (no different from foo:a) can have any
-	// namespaceURI for Element except null
-        Assertion.equals(doc.createElementNS("http://nsa", "xmlns:a").getNamespaceURI(), "http://nsa");
-        Assertion.equals(doc.createElementNS(xmlURI, "xmlns:a").getNamespaceURI(), xmlURI);
-	Assertion.assert(DOMExceptionsTest(doc, "createElementNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{null, "xmlns:a"},
-				      DOMException.NAMESPACE_ERR));
-
-        //In fact, any prefix != null should have a namespaceURI != null
-        Assertion.equals(doc.createElementNS("http://nsa", "foo:a").getNamespaceURI(), "http://nsa");
-	Assertion.assert(DOMExceptionsTest(doc, "createElementNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{null, "foo:a"},
-				      DOMException.NAMESPACE_ERR));
-
-        //Change prefix
-        Element elem = doc.createElementNS("http://nsa", "foo:a");
-        elem.setPrefix("bar");
-        Assertion.equals(elem.getNodeName(), "bar:a");
-        Assertion.equals(elem.getNamespaceURI(), "http://nsa");
-        Assertion.equals(elem.getPrefix(), "bar");
-        Assertion.equals(elem.getLocalName(), "a");
-        Assertion.equals(elem.getTagName(), "bar:a");
-        //The spec does not prevent us from setting prefix to a node without prefix
-        elem = doc.createElementNS("http://nsa", "a");
-        Assertion.equals(elem.getPrefix(), null);
-        elem.setPrefix("bar");
-        Assertion.equals(elem.getNodeName(), "bar:a");
-        Assertion.equals(elem.getNamespaceURI(), "http://nsa");
-        Assertion.equals(elem.getPrefix(), "bar");
-        Assertion.equals(elem.getLocalName(), "a");
-        Assertion.equals(elem.getTagName(), "bar:a");
-        //Special case for xml:a where namespaceURI must be xmlURI
-        elem = doc.createElementNS(xmlURI, "foo:a");
-        elem.setPrefix("xml");
-        elem = doc.createElementNS("http://nsa", "foo:a");
-        Assertion.assert(DOMExceptionsTest(elem, "setPrefix",
-					  new Class[]{String.class},
-					  new Object[]{"xml"},
-					  DOMException.NAMESPACE_ERR));
-        //However, there is no restriction on prefix xmlns
-        elem.setPrefix("xmlns");
-        //Also an element can not have a prefix with namespaceURI == null
-        elem = doc.createElementNS(null, "a");
-        Assertion.assert(DOMExceptionsTest(elem, "setPrefix",
-					  new Class[]{String.class},
-					  new Object[]{"foo"},
-					  DOMException.NAMESPACE_ERR));
-
-        //Only prefix of Element and Attribute can be changed
-        Assertion.assert(DOMExceptionsTest(doc, "setPrefix",
-					  new Class[]{String.class},
-					  new Object[]{"foo"},
-					  DOMException.NAMESPACE_ERR));
-
-        //Prefix of readonly Element can not be changed.
-        //However, there is no way to create such Element for testing yet.
-    }
-    
-
-
-
-    //
-    //  CreateAttributeNS methods
-    //
-    
-    {
-        
-        // Set up an initial (root element only) document.
-        // 
-        DOMImplementation impl = DOMImplementationImpl.getDOMImplementation();
-        
-        String qName = "foo:docName";
-        String pubId = "pubId";
-        String sysId = "http://sysId";
-        DocumentType dt = impl.createDocumentType(qName, pubId, sysId);
-        
-        String docNSURI = "http://document.namespace";
-        Document doc = impl.createDocument(docNSURI, qName, dt);
-        Element rootEl = doc.getDocumentElement();
-
-        //
-        // CreateAttributeNS
-        //
-        Attr attra = doc.createAttributeNS("http://nsa", "a:attra");       // prefix and URI
-        Attr attrb = doc.createAttributeNS("http://nsb", "attrb");         //  URI, no prefix.
-        Attr attrc = doc.createAttributeNS(null, "attrc");    // No URI, no prefix.
-
-        Assertion.equals(attra.getNodeName(), "a:attra");
-        Assertion.equals(attra.getNamespaceURI(), "http://nsa");
-        Assertion.equals(attra.getPrefix(), "a");
-        Assertion.equals(attra.getLocalName(), "attra");
-        Assertion.equals(attra.getName(), "a:attra");
-        Assertion.assert(attra.getOwnerElement() == null);
-
-        Assertion.equals(attrb.getNodeName(), "attrb");
-        Assertion.equals(attrb.getNamespaceURI(), "http://nsb");
-        Assertion.equals(attrb.getPrefix(), null);
-        Assertion.equals(attrb.getLocalName(), "attrb");
-        Assertion.equals(attrb.getName(), "attrb");
-        Assertion.assert(attrb.getOwnerElement() == null);
-
-        Assertion.equals(attrc.getNodeName(), "attrc");
-        Assertion.assert(attrc.getNamespaceURI() == null);
-        Assertion.assert(attrc.getPrefix() == null);
-        Assertion.equals(attrc.getLocalName(), "attrc");
-        Assertion.equals(attrc.getName(), "attrc");
-        Assertion.assert(attrc.getOwnerElement() == null);
-
-
-        // Badly formed qualified name
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", "<a"},
-				      DOMException.INVALID_CHARACTER_ERR));
-	Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", ":a"},
-				      DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", "a:"},
-				      DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", "a::a"},
-				      DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", "a:a:a"},
-				      DOMException.NAMESPACE_ERR));
-
-        // xml:a must have namespaceURI == "http://www.w3.org/XML/1998/namespace"
-        String xmlURI = "http://www.w3.org/XML/1998/namespace";
-        Assertion.equals(doc.createAttributeNS(xmlURI, "xml:a").getNamespaceURI(), xmlURI);
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", "xml:a"},
-				      DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"", "xml:a"},
-				      DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{null,  "xml:a"},
-				      DOMException.NAMESPACE_ERR));
-
-        //unlike Element, xmlns must have namespaceURI == "http://www.w3.org/2000/xmlns/"
-        String xmlnsURI = "http://www.w3.org/2000/xmlns/";
-        Assertion.equals(doc.createAttributeNS(xmlnsURI, "xmlns").getNamespaceURI(), xmlnsURI);
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", "xmlns"},
-				      DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{xmlURI, "xmlns"},
-				      DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"", "xmlns"},
-				      DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{null,  "xmlns"},
-				      DOMException.NAMESPACE_ERR));
-
-        //unlike Element, xmlns:a must have namespaceURI == "http://www.w3.org/2000/xmlns/"
-        Assertion.equals(doc.createAttributeNS(xmlnsURI, "xmlns:a").getNamespaceURI(), xmlnsURI);
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"http://nsa", "xmlns:a"},
-				      DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{xmlURI, "xmlns:a"},
-				      DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"", "xmlns:a"},
-				      DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{null,  "xmlns:a"},
-				      DOMException.NAMESPACE_ERR));
-
-        //In fact, any prefix != null should have a namespaceURI != null
-        Assertion.equals(doc.createAttributeNS("http://nsa", "foo:a").getNamespaceURI(), "http://nsa");
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{"", "foo:a"},
-				      DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(doc, "createAttributeNS",
-				      new Class[]{String.class, String.class},
-				      new Object[]{null,  "foo:a"},
-				      DOMException.NAMESPACE_ERR));
-
-        //Change prefix
-        Attr attr = doc.createAttributeNS("http://nsa", "foo:a");
-        attr.setPrefix("bar");
-        Assertion.equals(attr.getNodeName(), "bar:a");
-        Assertion.equals(attr.getNamespaceURI(), "http://nsa");
-        Assertion.equals(attr.getPrefix(), "bar");
-        Assertion.equals(attr.getLocalName(), "a");
-        Assertion.equals(attr.getName(), "bar:a");
-        //The spec does not prevent us from setting prefix to a node without prefix
-        attr = doc.createAttributeNS("http://nsa", "a");
-        Assertion.assert(attr.getPrefix() == null);
-        attr.setPrefix("bar");
-        Assertion.equals(attr.getNodeName(), "bar:a");
-        Assertion.equals(attr.getNamespaceURI(), "http://nsa");
-        Assertion.equals(attr.getPrefix(), "bar");
-        Assertion.equals(attr.getLocalName(), "a");
-        Assertion.equals(attr.getName(), "bar:a");
-        //Special case for xml:a where namespaceURI must be xmlURI
-        attr = doc.createAttributeNS(xmlURI, "foo:a");
-        attr.setPrefix("xml");
-        attr = doc.createAttributeNS("http://nsa", "foo:a");
-        Assertion.assert(DOMExceptionsTest(attr, "setPrefix",
-					   new Class[]{String.class},
-					   new Object[]{"xml"},
-					   DOMException.NAMESPACE_ERR));
-        //Special case for xmlns:a where namespaceURI must be xmlURI
-        attr = doc.createAttributeNS(xmlnsURI, "foo:a");
-        attr.setPrefix("xmlns");
-        attr = doc.createAttributeNS("http://nsa", "foo:a");
-        Assertion.assert(DOMExceptionsTest(attr, "setPrefix",
-					   new Class[]{String.class},
-					   new Object[]{"xmlns"},
-					   DOMException.NAMESPACE_ERR));
-        //Special case for xmlns where no prefix can be set
-        attr = doc.createAttributeNS(xmlnsURI, "xmlns");
-        Assertion.assert(DOMExceptionsTest(attr, "setPrefix",
-					   new Class[]{String.class},
-					   new Object[]{"xml"},
-					   DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(attr, "setPrefix",
-					   new Class[]{String.class},
-					   new Object[]{"foo"},
-					   DOMException.NAMESPACE_ERR));
-        Assertion.assert(DOMExceptionsTest(attr, "setPrefix",
-					   new Class[]{String.class},
-					   new Object[]{"xmlns"},
-					   DOMException.NAMESPACE_ERR));
-        //Also an attribute can not have a prefix with namespaceURI == null
-        attr = doc.createAttributeNS(null, "a");
-        Assertion.assert(DOMExceptionsTest(attr, "setPrefix",
-					   new Class[]{String.class},
-					   new Object[]{"foo"},
-					   DOMException.NAMESPACE_ERR));
-        
-        //Only prefix of Element and Attribute can be changed
-        Assertion.assert(DOMExceptionsTest(attr, "setPrefix",
-					   new Class[]{String.class},
-					   new Object[]{"foo"},
-					   DOMException.NAMESPACE_ERR));
-
-        //Prefix of readonly Attribute can not be changed.
-        //However, there is no way to create such DOM_Attribute for testing yet.
-    }
-    
-
-    //
-    //  getElementsByTagName*
-    //
-    
-    {
-        
-        // Set up an initial (root element only) document.
-        // 
-        DOMImplementation impl = DOMImplementationImpl.getDOMImplementation();
-        
-        String qName = "foo:docName";
-        String pubId = "pubId";
-        String sysId = "http://sysId";
-        DocumentType dt = impl.createDocumentType(qName, pubId, sysId);
-        
-        String docNSURI = "http://document.namespace";
-	Document doc = impl.createDocument(docNSURI, qName, dt);
-        Element rootEl = doc.getDocumentElement();
-
-        //
-        // Populate the document
-        //
-        Element ela = doc.createElementNS("http://nsa", "a:ela");  
-        rootEl.appendChild(ela);
-        Element elb = doc.createElementNS("http://nsb", "elb");   
-        rootEl.appendChild(elb);
-        Element elc = doc.createElementNS(null,           "elc");  
-        rootEl.appendChild(elc);
-        Element eld = doc.createElementNS("http://nsa", "d:ela");
-        rootEl.appendChild(eld);
-        Element ele = doc.createElementNS("http://nse", "elb");   
-        rootEl.appendChild(ele);
-
-
-        // 
-        // Access with DOM Level 1 getElementsByTagName
-        //
-
-        NodeList nl = doc.getElementsByTagName("a:ela");
-        Assertion.assert(nl.getLength() == 1);
-        Assertion.assert(nl.item(0) == ela);
-
-        nl = doc.getElementsByTagName("elb");
-        Assertion.assert(nl.getLength() == 2);
-        Assertion.assert(nl.item(0) == elb);
-        Assertion.assert(nl.item(1) == ele);
-
-        nl = doc.getElementsByTagName("d:ela");
-        Assertion.assert(nl.getLength() == 1);
-        Assertion.assert(nl.item(0) == eld);
-
-        //
-        //  Access with DOM Level 2 getElementsByTagNameNS
-        //
-
-        nl = doc.getElementsByTagNameNS(null, "elc");
-        Assertion.assert(nl.getLength() == 1);
-        Assertion.assert(nl.item(0) == elc);
-       
-        nl = doc.getElementsByTagNameNS("http://nsa", "ela");
-        Assertion.assert(nl.getLength() == 2);
-        Assertion.assert(nl.item(0) == ela);
-        Assertion.assert(nl.item(1) == eld);
-
-        nl = doc.getElementsByTagNameNS(null, "elb");
-        Assertion.assert(nl.getLength() == 0);
-
-        nl = doc.getElementsByTagNameNS("http://nsb", "elb");
-        Assertion.assert(nl.getLength() == 1);
-        Assertion.assert(nl.item(0) == elb);
-
-        nl = doc.getElementsByTagNameNS("*", "elb");
-        Assertion.assert(nl.getLength() == 2);
-        Assertion.assert(nl.item(0) == elb);
-        Assertion.assert(nl.item(1) == ele);
-
-        nl = doc.getElementsByTagNameNS("http://nsa", "*");
-        Assertion.assert(nl.getLength() == 2);
-        Assertion.assert(nl.item(0) == ela);
-        Assertion.assert(nl.item(1) == eld);
-
-        nl = doc.getElementsByTagNameNS("*", "*");
-        Assertion.assert(nl.getLength() == 6);     // Gets the document root element, plus 5 more
-
-        Assertion.assert(nl.item(6) == null);
-        // Assertion.assert(nl.item(-1) == 0);
-
-        nl = rootEl.getElementsByTagNameNS("*", "*");
-        Assertion.assert(nl.getLength() == 5);
-
-
-        nl = doc.getElementsByTagNameNS("http://nsa", "d:ela");
-        Assertion.assert(nl.getLength() == 0);
-
-
-        //
-        // Node lists are Live
-        //
-
-        nl = doc.getElementsByTagNameNS("*", "*");
-        NodeList nla = ela.getElementsByTagNameNS("*", "*");
-
-        Assertion.assert(nl.getLength() == 6); 
-        Assertion.assert(nla.getLength() == 0);
-
-        rootEl.removeChild(elc);
-        Assertion.assert(nl.getLength() == 5);
-        Assertion.assert(nla.getLength() == 0);
-
-        ela.appendChild(elc);
-        Assertion.assert(nl.getLength() == 6);
-        Assertion.assert(nla.getLength() == 1);
-    }
-
-
-   //
-    // Attributes and NamedNodeMaps.
-    //
-    {
-
-        // Set up an initial (root element only) document.
-        // 
-        DOMImplementation impl = DOMImplementationImpl.getDOMImplementation();
-        
-        String qName = "foo:docName";
-        String pubId = "pubId";
-        String sysId = "http://sysId";
-        DocumentType dt = impl.createDocumentType(qName, pubId, sysId);
-        
-        String docNSURI = "http://document.namespace";
-        Document doc = impl.createDocument(docNSURI, qName, dt);
-        Element rootEl = doc.getDocumentElement();
-
-        //
-        // Create a set of attributes and hang them on the root element.
-        //
-        Attr attra = doc.createAttributeNS("http://nsa", "a:attra");  
-        rootEl.setAttributeNodeNS(attra);
-        Attr attrb = doc.createAttributeNS("http://nsb", "attrb");   
-        rootEl.setAttributeNodeNS(attrb);
-        Attr attrc = doc.createAttributeNS(null,           "attrc");  
-        rootEl.setAttributeNodeNS(attrc);
-        Attr attrd = doc.createAttributeNS("http://nsa", "d:attra");
-        rootEl.setAttributeNodeNS(attrd);
-        Attr attre = doc.createAttributeNS("http://nse", "attrb");   
-        rootEl.setAttributeNodeNS(attre);
-
-        //
-        // Check that the attribute nodes were created with the correct properties.
-        //
-        Assertion.equals(attra.getNodeName(), "a:attra");
-        Assertion.equals(attra.getNamespaceURI(), "http://nsa");
-        Assertion.equals(attra.getLocalName(), "attra");
-        Assertion.equals(attra.getName(), "a:attra");
-        Assertion.assert(attra.getNodeType() == Node.ATTRIBUTE_NODE);
-        Assertion.equals(attra.getNodeValue(), "");
-        Assertion.equals(attra.getPrefix(), "a");
-        Assertion.assert(attra.getSpecified() == true);
-        Assertion.equals(attra.getValue(), "");
-        Assertion.assert(attra.getOwnerElement() == null);
-
-        // Test methods of NamedNodeMap
-        NamedNodeMap nnm = rootEl.getAttributes();
-        Assertion.assert(nnm.getLength() == 4);
-        Assertion.assert(nnm.getNamedItemNS("http://nsa", "attra") == attrd);
-        Assertion.assert(nnm.getNamedItemNS("http://nsb", "attrb") == attrb);
-        Assertion.assert(nnm.getNamedItemNS("http://nse", "attrb") == attre);
-        Assertion.assert(nnm.getNamedItemNS(null, "attrc") == attrc);
-        Assertion.assert(nnm.getNamedItemNS(null, "attra") == null);
-        Assertion.assert(nnm.getNamedItemNS("http://nsa", "attrb") == null);
-    }
-    };
-}    
diff --git a/tests/dom/range/Makefile b/tests/dom/range/Makefile
deleted file mode 100644
index fe34f2a..0000000
--- a/tests/dom/range/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-
-TARGETS= Test.class
-
-DIRS =
-
-TOP = ../../..
-include $(TOP)/src/Makefile.incl
diff --git a/tests/dom/range/Test.java b/tests/dom/range/Test.java
deleted file mode 100644
index 4e57ef1..0000000
--- a/tests/dom/range/Test.java
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package dom.range;
-import org.apache.xerces.parsers.*;
-import org.apache.xerces.dom.*;
-import org.apache.xerces.dom.DocumentImpl;
-
-import org.w3c.dom.*;
-import org.w3c.dom.Element;
-import org.w3c.dom.range.*;
-import org.w3c.dom.range.RangeException;
-
-import java.io.*;
-import dom.DOMWriter;
-import org.xml.sax.InputSource;
-
-/** This RangeTest tests all of the cases delineated as examples
- *  in the DOM Level 2 Range specification, and a few others.
- *  <p>These do not by any means completely test the API and 
- *  corner cases. 
- */
-public class Test {
-    
-    static final boolean DEBUG = false;
-    
-    static final String [] tests = {
-        "<FOO>AB<MOO>CD</MOO>CD</FOO>",
-        "<FOO>A<MOO>BC</MOO>DE</FOO>",
-        "<FOO>XY<BAR>ZW</BAR>Q</FOO>",
-        "<FOO><BAR1>AB</BAR1><BAR2/><BAR3>CD</BAR3></FOO>",
-        "<A><B><M/><C><D/><E/><F/><HELLO/></C><N/><O/></B>"+
-        "<Z><X/><Y/></Z>"+
-        "<G/><Q><V/><W/></Q></A>"
-    };
-    static final String [] deleteResult = {
-        "<FOO>ACD</FOO>",
-        "<FOO>A<MOO>B</MOO>E</FOO>",
-        "<FOO>X<BAR>W</BAR>Q</FOO>",
-        "<FOO><BAR1>A</BAR1><BAR3>D</BAR3></FOO>",
-        "<A><B><M></M><C><D></D></C></B><Q><W></W></Q></A>"
-    };
-    static final String [] extractResult = {
-        "B<MOO>CD</MOO>",
-        "<MOO>C</MOO>D",
-        "Y<BAR>Z</BAR>",
-        "<BAR1>B</BAR1><BAR2></BAR2><BAR3>C</BAR3>",
-        "<B><C><E></E><F></F><HELLO></HELLO></C>"+
-        "<N></N><O></O></B><Z><X></X><Y></Y></Z><G></G><Q><V></V></Q>"
-    };
-    
-    static final String INSERT="***";
-    static final String [] insertResult = {
-"<FOO>A"+INSERT+"B<MOO>CD</MOO>CD</FOO>",
-"<FOO>A<MOO>B"+INSERT+"C</MOO>DE</FOO>",
-"<FOO>X"+INSERT+"Y<BAR>ZW</BAR>Q</FOO>",
-"<FOO><BAR1>A"+INSERT+"B</BAR1><BAR2></BAR2><BAR3>CD</BAR3></FOO>",
-"<A><B><M></M><C><D></D>"+INSERT+"<E></E><F></F><HELLO></HELLO></C>"+
-"<N></N><O></O></B><Z><X></X><Y></Y></Z><G></G><Q><V></V><W></W></Q></A>"
-    };
-    
-
-    static final String SURROUND="SURROUND";
-
-    static final String [] surroundResult = {
-"<FOO>A<"+SURROUND+">B<MOO>CD</MOO>C</"+SURROUND+">D</FOO>",
-"<FOO>A<MOO>B<"+SURROUND+">C</"+SURROUND+"></MOO>DE</FOO>",
-"<FOO>X<"+SURROUND+">Y<BAR>ZW</BAR></"+SURROUND+">Q</FOO>",
-"<FOO><BAR1>AB</BAR1><"+SURROUND+"><BAR2></BAR2></"+SURROUND+"><BAR3>CD</BAR3></FOO>",
-"<A><B><M></M><C><D></D><E></E><F></F><HELLO></HELLO></C>"+
-"<N></N><O></O></B><Z><"+SURROUND+"><X></X><Y></Y></"+SURROUND+"></Z>"+
-"<G></G><Q><V></V><W></W></Q></A>"
-    };
-    
-    static final String [] rangeDelete = {
-    "<P>Abcd efgh The Range ijkl</P>",
-    "<p>Abcd efgh The Range ijkl</p>",
-    "<P>ABCD efgh The <EM>Range</EM> ijkl</P>",
-    "<P>Abcd efgh The Range ijkl</P>",
-    "<P>Abcd <EM>efgh The Range ij</EM>kl</P>"
-    };
-    //
-    static final String [] rangeDeleteResult = {
-    "<P>Abcd ^Range ijkl</P>",
-    "<p>Abcd ^kl</p>",
-    "<P>ABCD ^<EM>ange</EM> ijkl</P>",
-    "<P>Abcd ^he Range ijkl</P>",
-    "<P>Abcd ^kl</P>"
-    };
-    
-    static final String INSERT2="<P>Abcd efgh XY blah ijkl</P>";
-    static final String INSERTED_TEXT = "INSERTED TEXT";
-    
-    static final String [] rangeInsertResult = {
-    "<P>Abcd efgh INSERTED TEXTXY blah ijkl</P>",
-    "<P>Abcd efgh XINSERTED TEXTY blah ijkl</P>",
-    "<P>Abcd efgh XYINSERTED TEXT blah ijkl</P>",
-    "<P>Abcd efgh XY blahINSERTED TEXT ijkl</P>"
-    };
-    
-    
-    public static void main(String args[]) {
-        // is there anything to do?
-        if ( args.length == 0 ) {
-            printUsage();
-            System.exit(1);
-        }
-        new Test(args[0]);
-    }
-    
-   /** Prints the usage. */
-   private static void printUsage() {
-
-      System.err.println("usage: java dom.range.Test (options) ...");
-      System.err.println();
-      System.err.println("options:");
-      System.err.println("  all             all tests");
-      System.err.println("  delete          delete test");
-      System.err.println("  extract         extract test");
-      System.err.println("  clone           clone test");
-      System.err.println("  insert          insert test");
-      System.err.println("  surround        surround test");
-      System.err.println("  insert2         insert mutation test");
-      System.err.println("  delete2         delete mutation test");
-
-   } // printUsage()
-    
-    
-    public Test(String arg) {
-        if (arg.equals("all")) {
-            boolean all = false;
-            all = performTest("delete");
-            all = performTest("extract")&&all;
-            all = performTest("clone")&&all;
-            all = performTest("insert")&&all;
-            all = performTest("surround")&&all;
-            all = performTest("insert2")&&all;
-            all = performTest("delete2")&&all;
-            if (all) 
-                System.out.println("*** ALL TESTS PASSED! ***");
-            else 
-                System.out.println("*** ONE OR MORE TESTS FAILED! ***");
-            
-        } else {
-            performTest(arg);            
-        }
-    }
-    
-    public boolean performTest(String arg) {
-        boolean passed = true;
-        try {
-            DOMWriter writer = new DOMWriter(false);
-            DOMParser parser = new DOMParser();
-            if (!arg.equals("delete2") && !arg.equals("insert2")) {
-            System.out.println("\n*************** Test == "+arg+" ***************");
-            for (int i = 0; i < tests.length; i++) {
-                System.out.println("\n\nTest["+i+"]");
-                System.out.println("\nBefore "+arg+": document="+tests[i]+":");
-                parser.parse(new InputSource(new StringReader(tests[i])));
-                DocumentImpl document = (DocumentImpl)parser.getDocument();
-                Range range = document.createRange();
-                Node root = document.getDocumentElement();
-                boolean surround = false;
-                Node surroundNode=document.createElement(SURROUND);
-                if (arg.equals("surround")) {
-                    surround = true;
-                }
-                
-                if (i == 0) { 
-                    range.setStart(root.getFirstChild(), 1);
-                    range.setEndBefore(root.getLastChild());
-                    if (surround)
-                        range.setEnd(root.getLastChild(),1);
-                    
-                }
-                else if (i == 1) {
-                    Node n1 = root.getFirstChild().getNextSibling().
-                    getFirstChild();
-                    range.setStart(n1, 1);
-                    range.setEnd(root.getLastChild(), 1);
-                    if (surround)
-                        range.setEnd(n1,2);
-                }
-                else if (i == 2) {
-                    range.setStart(root.getFirstChild(), 1);
-                    Node n2 = root.getFirstChild().getNextSibling().getFirstChild();
-                    range.setEnd(n2, 1);
-                    if (surround)
-                        range.setEndBefore(root.getLastChild());
-                }
-                else if (i == 3) {
-                    Node n3 = root.getFirstChild().getFirstChild();
-                    range.setStart(n3, 1);
-                    range.setEnd(root.getLastChild().getFirstChild(), 1);
-                    if (surround) {
-                        range.selectNode(root.getFirstChild().getNextSibling());
-                    }
-                }
-                else if (i == 4) {
-                    Node n4 = root.getFirstChild().getFirstChild().getNextSibling().getFirstChild();
-                    range.setStartAfter(n4);
-                    range.setEndAfter(root.getLastChild().getFirstChild());
-                    if (surround) {
-                        range.selectNodeContents(root.getFirstChild().getNextSibling());
-                    }
-                }
-                
-                System.out.println("range.toString="+range.toString());
-                DocumentFragment frag = null;
-                
-                if (arg.equals("surround")) {
-                    try {
-                        System.out.println("surroundNode="+surroundNode);
-                        range.surroundContents(surroundNode);
-                    } catch (org.w3c.dom.range.RangeException e) {
-                        System.out.println(e);
-                    }
-                   String result = toString(document);
-                   System.out.println("After surround: document="+result+":");
-                   if (!result.equals(surroundResult[i])) {
-                        System.out.println("Should be: document="+surroundResult[i]+":");
-                        passed = false;
-                        System.out.println("Test FAILED!");
-                        System.out.println("*** Surround document Test["+i+"] FAILED!");
-                   }
-                }
-                
-                if (arg.equals("insert")) {
-                    range.insertNode(document.createTextNode(INSERT));
-                   String result = toString(document);
-                   System.out.println("After  insert: document="+result+":");
-                   if (!result.equals(insertResult[i])) {
-                        System.out.println("Should be: document="+insertResult[i]+":");
-                        passed = false;
-                        System.out.println("Test FAILED!");
-                        System.out.println("*** Insert document Test["+i+"] FAILED!");
-                   }
-                    
-                } else 
-                if (arg.equals("delete")) {
-                   range.deleteContents();
-                   String result = toString(document);
-                   System.out.println("After delete:"+result+":");
-                   if (!result.equals(deleteResult[i])) {
-                        System.out.println("Should be: document="+deleteResult[i]+":");
-                        passed = false;
-                        System.out.println("Test FAILED!");
-                        System.out.println("*** Delete document Test["+i+"] FAILED!");
-                   }
-                }
-                else 
-                if (arg.equals("extract")) {
-                    frag = range.extractContents();
-                    //range.insertNode(document.createTextNode("^"));
-                   String result = toString(document);
-                   System.out.println("After extract: document="+result+":");
-                   if (!result.equals(deleteResult[i])) {
-                        System.out.println("Should be: document="+deleteResult[i]+":");
-                        passed = false;
-                        System.out.println("*** Extract document Test["+i+"] FAILED!");
-                   }
-                   String fragResult = toString(frag);
-                   System.out.println("After extract: fragment="+fragResult+":");
-                   if (!fragResult.equals(extractResult[i])) {
-                        System.out.println("Should be: fragment="+extractResult[i]+":");
-                        passed = false;
-                        System.out.println("*** Extract Fragment Test["+i+"] FAILED!");
-                   }
-                }
-                   
-                else 
-                if (arg.equals("clone")) {
-                    frag = range.cloneContents();
-                   String fragResult = toString(frag);
-                   System.out.println("After clone: fragment="+fragResult);
-                   if (!fragResult.equals(extractResult[i])) {
-                        System.out.println("Should be: fragment="+extractResult[i]+":");
-                        passed = false;
-                        System.out.println("*** Clone Fragment Test["+i+"] FAILED!");
-                   }
-                }
-                
-            }
-            
-            } else
-            if (arg.equals("insert2")) {
-            System.out.println("\n*************** Test == "+arg+" ***************");
-            for (int i = 0; i < 4; i++) {
-
-                System.out.println("\n\nTest["+i+"]");
-                System.out.println("\nBefore "+arg+": document="+INSERT2+":");
-                parser.parse(new InputSource(new StringReader(INSERT2)));
-                DocumentImpl document = (DocumentImpl)parser.getDocument();
-                Node root = document.getDocumentElement();
-                Range range = document.createRange();
-                range.setStart(root.getFirstChild(),11);
-                range.setEnd(root.getFirstChild(),18);
-                Range rangei = document.createRange();
-                if (i == 0) { 
-                    rangei.setStart(root.getFirstChild(), 10);
-                    rangei.setEnd(root.getFirstChild(), 10);
-                }
-                if (i == 1) { 
-                    rangei.setStart(root.getFirstChild(), 11);
-                    rangei.setEnd(root.getFirstChild(), 11);
-                }
-                if (i == 2) { 
-                    rangei.setStart(root.getFirstChild(), 12);
-                    rangei.setEnd(root.getFirstChild(), 12);
-                }
-                if (i == 3) { 
-                    rangei.setStart(root.getFirstChild(), 17);
-                    rangei.setEnd(root.getFirstChild(), 17);
-                }
-                //System.out.println("range: start1=="+range.getStartContainer());
-                //root.insertBefore(document.createTextNode("YES!"), root.getFirstChild());
-                //System.out.println("range: start2=="+range.getStartContainer());
-   
-                if (DEBUG) System.out.println("before insert start="+range.getStartOffset());
-                if (DEBUG) System.out.println("before insert end="+range.getEndOffset());
-                rangei.insertNode(document.createTextNode(INSERTED_TEXT));
-                if (DEBUG) System.out.println("after insert start="+range.getStartOffset());
-                if (DEBUG) System.out.println("after insert end="+range.getEndOffset());
-                
-                String result = toString(document);
-                System.out.println("After insert2: document="+result+":");
-                if (!result.equals(rangeInsertResult[i])) {
-                    System.out.println("Should be: document="+rangeInsertResult[i]+":");
-                    passed = false;
-                    System.out.println("Test FAILED!");
-                    System.out.println("*** Delete Ranges document Test["+i+"] FAILED!");
-                }
-            }
-            } else
-            if (arg.equals("delete2")) {
-            //
-            // Range Deletion, acting upon another range.
-            //
-       
-            System.out.println("\n*************** Test == "+arg+" ***************");
-            for (int i = 0; i < rangeDelete.length; i++) {
-                System.out.println("\n\nTest["+i+"]");
-                System.out.println("\nBefore "+arg+": document="+rangeDelete[i]+":");
-                parser.parse(new InputSource(new StringReader(rangeDelete[i])));
-                DocumentImpl document = (DocumentImpl)parser.getDocument();
-                Range range = document.createRange();
-                Range ranged = document.createRange();
-                Node root = document.getDocumentElement();
-                boolean surround = false;
-                Node surroundNode=document.createElement(SURROUND);
-                if (arg.equals("surround")) {
-                    surround = true;
-                }
-                
-                if (i == 0) { 
-                    ranged.setStart(root.getFirstChild(), 5);
-                    ranged.setEnd(root.getFirstChild(), 14);
-                    
-                    range.setStart(root.getFirstChild(), 11);
-                    range.setEnd(root.getFirstChild(), 19);
-                }
-                else if (i == 1) {
-                    ranged.setStart(root.getFirstChild(), 5);
-                    ranged.setEnd(root.getFirstChild(), 22);
-                    
-                    range.setStart(root.getFirstChild(), 11);
-                    range.setEnd(root.getFirstChild(), 21);
-                }
-                else if (i == 2) {
-                    ranged.setStart(root.getFirstChild(), 5);
-                    ranged.setEnd(root.getFirstChild().getNextSibling()
-                        .getFirstChild(), 1);
-                        
-                    range.setStart(root.getFirstChild(), 11);
-                    
-                    range.setEndAfter(root.getFirstChild().getNextSibling()
-                        .getFirstChild());
-                }
-                else if (i == 3) {
-                    ranged.setStart(root.getFirstChild(), 5);
-                    ranged.setEnd(root.getFirstChild(), 11);
-                    
-                    range.setStart(root.getFirstChild(), 11);
-                    range.setEnd(root.getFirstChild(), 21);
-                }
-                else if (i == 4) {
-                    ranged.selectNode(root.getFirstChild().getNextSibling());
-                    
-                    range.setStart(root.getFirstChild().getNextSibling()
-                        .getFirstChild(), 6);
-                    range.setEnd(root.getFirstChild().getNextSibling()
-                        .getFirstChild(), 15);
-                }
-                
-                DocumentFragment frag = null;
-                
-                if (arg.equals("delete2")) {
-                    if (DEBUG) {
-                   System.out.println("BEFORE deleteContents()");
-                   System.out.println("ranged: startc="+ranged.getStartContainer());
-                   System.out.println("ranged: starto="+ranged.getStartOffset());
-                   System.out.println("ranged:   endc="+ranged.getEndContainer());
-                   System.out.println("ranged:   endo="+ranged.getEndOffset());
-             
-                   System.out.println("range: startc="+range.getStartContainer());
-                   System.out.println("range: starto="+range.getStartOffset());
-                   System.out.println("range:   endc="+range.getEndContainer());
-                   System.out.println("range:   endo="+range.getEndOffset());
-                    }
-                   ranged.deleteContents();
-                   String result = null;
-                   if (DEBUG) {
-                   System.out.println("AFTER deleteContents()");
-                   result = toString(document);
-                   System.out.println("ranged: startc="+ranged.getStartContainer());
-                   System.out.println("ranged: starto="+ranged.getStartOffset());
-                   System.out.println("ranged:   endc="+ranged.getEndContainer());
-                   System.out.println("ranged:   endo="+ranged.getEndOffset());
-             
-                   System.out.println("range: startc="+range.getStartContainer());
-                   System.out.println("range: starto="+range.getStartOffset());
-                   System.out.println("range:   endc="+range.getEndContainer());
-                   System.out.println("range:   endo="+range.getEndOffset());
-                   }
-                   
-                   ranged.insertNode(document.createTextNode("^"));
-                   
-                   result = toString(document);
-                   System.out.println("After delete2: document="+result+":");
-                   if (!result.equals(rangeDeleteResult[i])) {
-                        System.out.println("Should be: document="+rangeDeleteResult[i]+":");
-                        passed = false;
-                        System.out.println("Test FAILED!");
-                        System.out.println("*** Delete Ranges document Test["+i+"] FAILED!");
-                   }
-                }
-            }
-                
-            }
-            
-       
-        }
-        catch (org.xml.sax.SAXParseException spe) {
-            passed = false;
-        }
-        catch (org.xml.sax.SAXException se) {
-            if (se.getException() != null)
-                se.getException().printStackTrace(System.err);
-            else
-                se.printStackTrace(System.err);
-            passed = false;
-        }
-        catch (Exception e) {
-            e.printStackTrace(System.err);
-            passed = false;
-        }
-        if (!passed) System.out.println("*** The "+arg+" Test FAILED! ***");
-        
-        return passed;
-    }
-    StringBuffer sb;
-    boolean canonical = true;
-    
-    String toString(Node node) {
-        sb = new StringBuffer();
-        return print(node);
-    
-    }
-   
-   /** Prints the specified node, recursively. */
-   public String print(Node node) {
-
-      // is there anything to do?
-      if ( node == null ) {
-         return sb.toString();
-      }
-
-      int type = node.getNodeType();
-      switch ( type ) {
-         // print document
-         case Node.DOCUMENT_NODE: {
-               return print(((Document)node).getDocumentElement());
-               //out.flush();
-               //break;
-            }
-
-            // print element with attributes
-         case Node.ELEMENT_NODE: {
-               sb.append('<');
-               sb.append(node.getNodeName());
-               Attr attrs[] = sortAttributes(node.getAttributes());
-               for ( int i = 0; i < attrs.length; i++ ) {
-                  Attr attr = attrs[i];
-                  sb.append(' ');
-                  sb.append(attr.getNodeName());
-                  sb.append("=\"");
-                  sb.append(normalize(attr.getNodeValue()));
-                  sb.append('"');
-               }
-               sb.append('>');
-               NodeList children = node.getChildNodes();
-               if ( children != null ) {
-                  int len = children.getLength();
-                  for ( int i = 0; i < len; i++ ) {
-                     print(children.item(i));
-                  }
-               }
-               break;
-            }
-
-            // handle entity reference nodes
-         case Node.ENTITY_REFERENCE_NODE: {
-               if ( canonical ) {
-                  NodeList children = node.getChildNodes();
-                  if ( children != null ) {
-                     int len = children.getLength();
-                     for ( int i = 0; i < len; i++ ) {
-                        print(children.item(i));
-                     }
-                  }
-               } else {
-                  sb.append('&');
-                  sb.append(node.getNodeName());
-                  sb.append(';');
-               }
-               break;
-            }
-
-            // print cdata sections
-         case Node.CDATA_SECTION_NODE: {
-               if ( canonical ) {
-                  sb.append(normalize(node.getNodeValue()));
-               } else {
-                  sb.append("<![CDATA[");
-                  sb.append(node.getNodeValue());
-                  sb.append("]]>");
-               }
-               break;
-            }
-
-            // print text
-         case Node.TEXT_NODE: {
-               sb.append(normalize(node.getNodeValue()));
-               break;
-            }
-
-            // print processing instruction
-         case Node.PROCESSING_INSTRUCTION_NODE: {
-               sb.append("<?");
-               sb.append(node.getNodeName());
-               String data = node.getNodeValue();
-               if ( data != null && data.length() > 0 ) {
-                  sb.append(' ');
-                  sb.append(data);
-               }
-               sb.append("?>");
-               break;
-            }
-            // handle entity reference nodes
-         case Node.DOCUMENT_FRAGMENT_NODE: {
-            NodeList children = node.getChildNodes();
-            if ( children != null ) {
-                int len = children.getLength();
-                for ( int i = 0; i < len; i++ ) {
-                     print(children.item(i));
-                }
-            }
-               break;
-            }
-      }
-
-      if ( type == Node.ELEMENT_NODE ) {
-         sb.append("</");
-         sb.append(node.getNodeName());
-         sb.append('>');
-      }
-
-      return sb.toString();
-
-   } // print(Node)
-
-   /** Returns a sorted list of attributes. */
-   protected Attr[] sortAttributes(NamedNodeMap attrs) {
-
-      int len = (attrs != null) ? attrs.getLength() : 0;
-      Attr array[] = new Attr[len];
-      for ( int i = 0; i < len; i++ ) {
-         array[i] = (Attr)attrs.item(i);
-      }
-      for ( int i = 0; i < len - 1; i++ ) {
-         String name  = array[i].getNodeName();
-         int    index = i;
-         for ( int j = i + 1; j < len; j++ ) {
-            String curName = array[j].getNodeName();
-            if ( curName.compareTo(name) < 0 ) {
-               name  = curName;
-               index = j;
-            }
-         }
-         if ( index != i ) {
-            Attr temp    = array[i];
-            array[i]     = array[index];
-            array[index] = temp;
-         }
-      }
-
-      return (array);
-
-   } // sortAttributes(NamedNodeMap):Attr[]
-    
-   /** Normalizes the given string. */
-   protected String normalize(String s) {
-      StringBuffer str = new StringBuffer();
-
-      int len = (s != null) ? s.length() : 0;
-      for ( int i = 0; i < len; i++ ) {
-         char ch = s.charAt(i);
-         switch ( ch ) {
-            case '<': {
-                  str.append("&lt;");
-                  break;
-               }
-            case '>': {
-                  str.append("&gt;");
-                  break;
-               }
-            case '&': {
-                  str.append("&amp;");
-                  break;
-               }
-            case '"': {
-                  str.append("&quot;");
-                  break;
-               }
-            case '\r':
-            case '\n': {
-                  if ( canonical ) {
-                     str.append("&#");
-                     str.append(Integer.toString(ch));
-                     str.append(';');
-                     break;
-                  }
-                  // else, default append char
-               }
-            default: {
-                  str.append(ch);
-               }
-         }
-      }
-
-      return (str.toString());
-
-   } // normalize(String):String
-   
-    
-}
diff --git a/tests/dom/serialize/Makefile b/tests/dom/serialize/Makefile
deleted file mode 100644
index de8dc56..0000000
--- a/tests/dom/serialize/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-
-TARGETS= TestSerializeDOMIn.class \
-	TestSerializeDOMOut.class
-
-DIRS =
-
-TOP = ../../..
-include $(TOP)/src/Makefile.incl
-CLPATH := $(TOP)/tests;${CLPATH}
-
diff --git a/tests/dom/serialize/TestSerializeDOMIn.java b/tests/dom/serialize/TestSerializeDOMIn.java
deleted file mode 100644
index 68c92ca..0000000
--- a/tests/dom/serialize/TestSerializeDOMIn.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package dom.serialize;
-import java.io.ObjectInputStream;
-import org.apache.xerces.dom.DocumentImpl;
-import org.apache.xerces.dom.DeferredDocumentImpl;
-import org.w3c.dom.NodeList;
-import org.apache.xerces.dom.NodeImpl;
-import org.w3c.dom.Document;
-import java.io.FileInputStream;
-import org.w3c.dom.Node;
-import dom.DOMWriter;
-import dom.serialize.*;
-
-
-/**
- * This testcase tests the Java Serialization
- * of the DOM.
- * I wrote this to test this capability for
- * regresion
- * 
- * @author Jeffrey Rodriguez
- * @version $id$
- * @see                      TestSerializeDOMIn
- */
-public class TestSerializeDOMIn {
-
-    public TestSerializeDOMIn() {
-    }
-
-
-    /**
-     * Serializes Java DOM Object 
-     * 
-     * @param nameSerializeFile
-     * @return 
-     */
-    public DocumentImpl deserializeDOM( String nameSerializedFile ){
-        ObjectInputStream in   = null;
-        DocumentImpl      doc  = null;
-        try {
-
-            FileInputStream fileIn = new FileInputStream( nameSerializedFile );
-            in                     = new ObjectInputStream(fileIn);
-            doc                    = (DocumentImpl) in.readObject();//Deserialize object
-        } catch ( Exception ex ) {
-            ex.printStackTrace();
-        }
-        return doc;
-    }
-
-
-    public static void main( String argv[]  ){
-        if ( argv.length != 2 ) {
-            System.out.println("Error - Usage: java TestSerializeDOMIn yourFile.ser elementName" );
-            System.exit(1);
-        }
-
-        String    xmlFilename = argv[0];
-
-        TestSerializeDOMIn         tst  = new TestSerializeDOMIn();
-        DocumentImpl   doc  = tst.deserializeDOM( xmlFilename );
-
-        NodeList nl         = doc.getElementsByTagName( argv[1]);
-
-
-        int length      = nl.getLength();
-
-        if ( length == 0 )
-            System.out.println(argv[1] + ": is not in the document!");
-
-        NodeImpl node = null;
-        for ( int i = 0;i<length;i++ ){
-            node                = (NodeImpl) nl.item(i);
-            Node childOfElement = node.getFirstChild();
-            if ( childOfElement != null ){
-                System.out.println( node.getNodeName() + ": " +
-                                    childOfElement.getNodeValue() );
-            }
-        }
-        try {
-           DOMWriter prettyWriter = new DOMWriter( false );
-           System.out.println( "Here is the whole Document" );
-           prettyWriter.print(  doc.getDocumentElement() );
-        } catch( Exception ex ){
-        }
-    }
-}
diff --git a/tests/dom/serialize/TestSerializeDOMOut.java b/tests/dom/serialize/TestSerializeDOMOut.java
deleted file mode 100644
index b06b9b7..0000000
--- a/tests/dom/serialize/TestSerializeDOMOut.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package dom.serialize;
-import java.io.ObjectOutputStream;
-import org.apache.xerces.parsers.DOMParser;
-import org.apache.xerces.dom.DocumentImpl;
-import org.apache.xerces.dom.DeferredDocumentImpl;
-import org.w3c.dom.NodeList;
-import org.apache.xerces.dom.NodeImpl;
-import org.w3c.dom.Document;
-import java.io.FileOutputStream;
-import org.w3c.dom.Node;
-import dom.DOMWriter;
-
-
-/**
- * This testcase tests the Java Serialization
- * of the DOM.
- * I wrote this to test this capability for
- * regresion
- * 
- * @author Jeffrey Rodriguez
- * @version $id$
- * @see                      TestSerializeDOMOut
- */
-
-
-public class TestSerializeDOMOut
-{          
-
-    public TestSerializeDOMOut(){
-    }
-
-      /**
-     * Deserializes Java DOM Object 
-     * 
-     * @param nameSerializeFile
-     * @return 
-     */
-    public void serializeDOM( Document doc, String nameSerializedFile ){
-        try {
-            ObjectOutputStream out               =
-                              new ObjectOutputStream( new FileOutputStream( nameSerializedFile ) );
-            out.writeObject(doc);
-            out.close();
-
-        } catch ( Exception ex ) {
-            ex.printStackTrace();
-        }
-    }
-
-
-    public static void main (String[] argv) 
-    { 
-
-        if ( argv.length != 1 ) {
-            System.out.println("Error - Usage: java TestOut yourFile.xml" );
-            System.exit(1);
-        }
-
-        String    xmlFilename = argv[0];
-
-
-        try {
-            DOMParser parser     = new DOMParser();
-
-            parser.parse( xmlFilename ); 
-
-            DocumentImpl doc     = (DocumentImpl) parser.getDocument();
-
-            int indexOfextension = xmlFilename.indexOf("." );
-
-
-
-            String nameOfSerializedFile = null;
-
-            if ( indexOfextension == -1 ) {
-                nameOfSerializedFile = xmlFilename +".ser" ;
-            } else {
-                nameOfSerializedFile = 
-                xmlFilename.substring(0,indexOfextension) + ".ser";
-            }
-
-            System.out.println( "Writing Serialize DOM  to file = " + nameOfSerializedFile ); 
-
-
-            FileOutputStream fileOut =  new FileOutputStream( nameOfSerializedFile );
-
-
-            TestSerializeDOMOut  tstOut = new TestSerializeDOMOut();
-
-            tstOut.serializeDOM( doc, nameOfSerializedFile );
-
-
-            System.out.println( "Reading Serialize DOM from " + nameOfSerializedFile );
-
-
-            TestSerializeDOMIn    tstIn  = new TestSerializeDOMIn();
-            doc           = tstIn.deserializeDOM( nameOfSerializedFile );
-
-            DOMWriter prettyWriter = new DOMWriter( false );
-            System.out.println( "Here is the whole Document" );
-            prettyWriter.print(  doc.getDocumentElement() );
-        } catch ( Exception ex ){
-            ex.printStackTrace();
-        }
-    } 
-}
-
diff --git a/tests/dom/util/Assertion.java b/tests/dom/util/Assertion.java
deleted file mode 100644
index ffd0e89..0000000
--- a/tests/dom/util/Assertion.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/* $Id$ */
-/*
- * The Apache Software License, Version 1.1
- * 
- * Copyright (c) 1999 The Apache Software Foundation.  All rights 
- * reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- * 
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- * 
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
- *    permission, please contact apache\@apache.org.
- * 
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- * 
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- * 
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation, and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.ibm.com .  For more information
- * on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-/**
- * A simple Assertion class (a hack really ;-) to report the source line number
- * where an assertion fails.
- */
-
-
-package dom.util;
-
-import java.io.StringWriter;
-import java.io.PrintWriter;
-
-public class Assertion {
-
-    public static boolean assert(boolean result) {
-	return assert(result, null);
-    }
-
-    public static boolean assert(boolean result, String error) {
-	if (!result) {
-	    System.err.print("Assertion failed: ");
-	    if (error != null) {
-		System.err.print(error);
-	    }
-	    System.err.println();
-	    System.err.println(getSourceLocation());
-	}
-	return result;
-    }
-
-    public static boolean equals(String s1, String s2) {
-        boolean result = ((s1 != null && s1.equals(s2))
-			  || (s1 == null && s2 == null));
-	if (!result) {
-	    assert(result);
-	    System.err.println("  was: equals(" + s1 + ", \"" + s2 + "\")");
-	}
-	return result;
-    }
-
-    public static String getSourceLocation() {
-	RuntimeException ex = new RuntimeException("assertion failed");
-	StringWriter writer = new StringWriter();
-	PrintWriter printer = new PrintWriter(writer);
-	ex.printStackTrace(printer);
-	String buf = writer.toString();
-	// skip the first line as well as every line related to this class
-	int index = buf.lastIndexOf("dom.util.Assertion.");
-	index = buf.indexOf('\n', index);
-	return buf.substring(index + 1);
-    }
-}
diff --git a/tests/dom/util/Makefile b/tests/dom/util/Makefile
deleted file mode 100644
index df7da53..0000000
--- a/tests/dom/util/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-
-TARGETS= Assertion.class
-
-DIRS =
-
-TOP = ../../..
-include $(TOP)/src/Makefile.incl
diff --git a/tools/ant.jar b/tools/ant.jar
deleted file mode 100644
index ee8bd00..0000000
--- a/tools/ant.jar
+++ /dev/null
Binary files differ
diff --git a/tools/style-apachexml.jar b/tools/style-apachexml.jar
deleted file mode 100644
index ea06a17..0000000
--- a/tools/style-apachexml.jar
+++ /dev/null
Binary files differ
diff --git a/tools/stylebook-1.0-b2.jar b/tools/stylebook-1.0-b2.jar
deleted file mode 100644
index 4e31e9c..0000000
--- a/tools/stylebook-1.0-b2.jar
+++ /dev/null
Binary files differ
diff --git a/tools/xalan.jar b/tools/xalan.jar
deleted file mode 100644
index f6827f6..0000000
--- a/tools/xalan.jar
+++ /dev/null
Binary files differ
diff --git a/tools/xerces.jar b/tools/xerces.jar
deleted file mode 100644
index 0766fd7..0000000
--- a/tools/xerces.jar
+++ /dev/null
Binary files differ
